java基础之类型信息

       

         这次主要学习java是如何在运行时识别对象和类的信息的。主要包括了两种方式:①RTTI(Run-Time Type Information)②反射。它们都可以使我们在运行时能够识别对象的类型信息。

        首先我们应当知道类型信息在java中是如何表示的。我们可以看到一个java类进行编译时会产生一个同名的class文件,这里就保存着该java类对应的Class对象,Class对象可以用来创建其他的对象以及类的RTTI。所有的类在第一次被使用时都会被加载到JVM中,但我们需要注意的是Java程序在开始运行之前并不是被完全加载的而是动态加载的。获取Class对象有一下三种方法:

①Class.forName()

②类名.class

③对象.getClass()

其中③是在已经拥有到实际的对象,然后通过getClass()获取该类的Class对象的引用。

①和②都可以获取到Class对象但是又存在些许的区别,使用.class语法来获得对类的引用不会触发对类的初始化,而使用①就会立即触发对类的初始化。

可以通过下面的代码看出来:

 

Java代码   收藏代码
  1. class Initable {  
  2.       static final int staticFinal = 47;  
  3.       static final int staticFinal2 =  
  4.         ClassInitialization.rand.nextInt(1000);  
  5.       static {  
  6.         System.out.println("Initializing Initable");  
  7.       }  
  8.     }  
  9.   
  10.     class Initable2 {  
  11.       static int staticNonFinal = 147;  
  12.       static {  
  13.         System.out.println("Initializing Initable2");  
  14.       }  
  15.     }  
  16.   
  17.     class Initable3 {  
  18.       static int staticNonFinal = 74;  
  19.       static {  
  20.         System.out.println("Initializing Initable3");  
  21.       }  
  22.     }  
  23.   
  24.     public class ClassInitialization {  
  25.       public static Random rand = new Random(47);  
  26.       @SuppressWarnings({ "unused""rawtypes" })  
  27.     public static void main(String[] args) throws Exception {  
  28.         Class initable = Initable.class;  
  29.         System.out.println("After creating Initable ref");  
  30.         System.out.println(Initable.staticFinal);  
  31.         System.out.println(Initable.staticFinal2);  
  32.         System.out.println(Initable2.staticNonFinal);  
  33.         Class initable3 = Class.forName("Initable3");  
  34.         System.out.println("After creating Initable3 ref");  
  35.         System.out.println(Initable3.staticNonFinal);  
  36.       }  
  37.     }  

 输出结果为:

 

After creating Initable ref
47
Initializing Initable
258
Initializing Initable2
147
Initializing Initable3
After creating Initable3 ref
74

在获取到Class对象以后我们就是通过Class对象的一些方法获取到更多的信息,例如getMehthod(),getConstructor()等。

②如果我们在编译时不知道获取对象的确切类型,此时我们可以使用反射。下面是一个动态代理的例子。

 

Java代码   收藏代码
  1. class MethodSelector implements InvocationHandler {  
  2.   private Object proxied;  
  3.   public MethodSelector(Object proxied) {  
  4.     this.proxied = proxied;  
  5.   }  
  6.   public Object  
  7.   invoke(Object proxy, Method method, Object[] args)  
  8.   throws Throwable {  
  9.     if(method.getName().equals("interesting"))  
  10.       System.out.println("Proxy detected the interesting method");  
  11.     return method.invoke(proxied, args);  
  12.   }  
  13. }     
  14.   
  15. interface SomeMethods {  
  16.   void boring1();  
  17.   void boring2();  
  18.   void interesting(String arg);  
  19.   void boring3();  
  20. }  
  21.   
  22. class Implementation implements SomeMethods {  
  23.   public void boring1() { System.out.println("boring1"); }  
  24.   public void boring2() { System.out.println("boring2"); }  
  25.   public void interesting(String arg) {  
  26.       System.out.println("interesting " + arg);  
  27.   }  
  28.   public void boring3() { System.out.println("boring3"); }  
  29. }     
  30.   
  31. class SelectingMethods {  
  32.   public static void main(String[] args) {  
  33.     SomeMethods proxy= (SomeMethods)Proxy.newProxyInstance(  
  34.       SomeMethods.class.getClassLoader(),  
  35.       new Class[]{ SomeMethods.class },  
  36.       new MethodSelector(new Implementation()));  
  37.     proxy.boring1();  
  38.     proxy.boring2();  
  39.     proxy.interesting("bonobo");  
  40.     proxy.boring3();  
  41.   }  
  42. }   

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值