14.类型信息

 

14.1为什么需要RTTI

java通过以下两种方式在运行的时候获取类和对象的信息。
1.传统的RTTI(runtime type information),编译的时候
2.反射,运行的时候
3.Class对象包含了与类有关的信息。每个类都有一个Class对象,每当编写并且编译了一个新类,都    会产生一个Class对象,更确切的说,是被保存到一个同名的.class文件中。
4.JVM使用“类加载器”来生成Class对象。

14.2 Class对象

类是程序的一部分,每个类都有一个Class对象,换言之,每当编写编译一个新类,就会产生一个Class对象。为了生成这个类的对象,JVM需要使用“类加载器”。


 类在什么时候被加载?
1.所有的类都在第一次使用时,被动态加载到JVM中。按需加载
2.当程序创建第一个对类的静态成员的引用时,就会加载这个类。(这也证明构造器是类的无static标明的特殊静态方法)

 static块
1.static{}(即static块),会在类被加载的时候执行且仅会被执行一次,一般用来初始化静态变量和调用静态方法
2.static块的执行顺序遵循定义顺序。
3.调用类的静态常量的时候,是不会加载类的,即不会执行static块。
4.用Class.forName()形式的时候,我们也可以自己设定要不要加载类。如将Class.forName("Test")改为Class.forName("Test",false,StaticBlockTest.class.getClassLoader()),你会发现程序什么都没有输出,即Test没有被加载,static{}没有被执行。

 获取Class的几种方法
1.
Class.forName("com.nuaa.Test");
2.
Test test=new Test();
test.getClass();
3.Test.class//类字面常量
第3种方法不仅简单,而且更安全,因为他在编译时就会受到检查,不需要放在try...catch中。此外,.class方法不会让类被加载。
还可以应用于基本数据类型。

14.3 类型转换前先做检查

14.4 注册工厂

工厂方法设计模式,将对象的创建工作交给类自己去完成。

com/nuaa/typeInfomation/Factory.java

1 package com.nuaa.typeInformation;
2 
3 public interface Factory<T> {
4     T create();
5 }

com/nuaa/typeInfomation/RegisteredFactories.java

 

 1 package com.nuaa.typeInformation;
 2 
 3 
 4 class Part{
 5     public String toString(){
 6         return getClass().getSimpleName();
 7     }
 8 }
 9 
10 class Filter extends Part{}
11 class FuelFilter extends Filter{
12     public static class Factory implements com.nuaa.typeInformation.Factory<FuelFilter>{
13         public FuelFilter create(){
14             return new FuelFilter();
15         }
16     }
17     
18     String value1="hello world";
19 
20     public String getValue1() {
21         return value1;
22     }
23 
24     public void setValue1(String value1) {
25         this.value1 = value1;
26     }
27 }
28 
29 class AirFilter extends Filter{
30     public static class Factory implements com.nuaa.typeInformation.Factory<AirFilter>{
31         public AirFilter create(){
32             return new AirFilter();
33         }
34     }
35 }
36 
37 class Belt extends Part{}
38 class FanBelt extends Belt{
39     public static class Factory implements com.nuaa.typeInformation.Factory<FanBelt>{
40         public FanBelt create(){
41             return new FanBelt();
42         }
43     }
44 }
45 
46 
47 
48 public class RegisteredFactories {
49     public static void main(String[] args){
50         System.out.println(new FuelFilter.Factory().create().getValue1());
51     }
52 }

 

output:
hello world

 

 

14.5 instanceof和Class的等价性

instanceof、isInstance、equals和==

instanceof和isInstance显示结果一样,考虑了继承;
equals和==显示结果一样,未考虑继承。

14.6 反射:运行时的类信息

反射机制

适用情形:已知一个对象引用,但并不知道它所属的类。例如,从磁盘文件,或者网络连接中获取了一串字节,并且被告知是一个对象,那么我们该如何使用它呢?

package com.nuaa.typeInformation;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

class PersonInfo{
    String name;
    int age;
    String addr;
    //无参数
    public String toString(){
        String str=name+","+age+"addr";
        System.out.println(str);
        return str;
    }
    //有参数
    public void toString1(String arg){
        System.out.println(arg);
    }
}

public class GetMethods {
    public static void main(String[] args){
        Object obj=null;
        Class clazz=PersonInfo.class;
        try {
            obj=clazz.newInstance();
        } catch (InstantiationException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (IllegalAccessException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        try {
            //Method method=clazz.getMethod("toString");
            Method method=clazz.getMethod("toString1",String.class);
            try {
                
                
                method.invoke(obj);
                method.invoke(obj,"hello world");
                
                
                
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

 

posted @ 2017-08-01 15:22  晨钟初磬  阅读(112)  评论(0)    收藏  举报