Java 反射机制

1.Class 类

  所有的类都是java.lang.Class类的实例。 通过a1,a2,a3,a4四种方式获得Class类实例。

  通过已知不同的条件,或者为类名A,可通过Class a1 = A.class方式获取类,如果知道实例可以通过Class a2 = a.getClass();效果一样。

public class AboutClass {
    public static void main(String[] args) {
        A a = new A();
        Class a1 = A.class;  //任何事物皆是对象,类A是Class类的对象
        Class a2 = a.getClass();  //a1,a2 表示了A类的类类型
        System.out.println("a1=a2是"+(a1==a2));
        try{
            Class a3 = Class.forName("com.project.reflect.A"); //全路径
            System.out.println("a1=a3是"+(a1==a3));
        }catch(Exception e){
            e.printStackTrace();
        }
        try {
            A a4 = (A) a1.newInstance(); //A必须有无参构造方法
            a4.print();
        } catch (Exception e) {
            
            e.printStackTrace();
        } 
        
    }
}

class A{
    public A(){
        
    };
    public void print(){
        System.out.println("this is A");
    }
}

运行结果为:

                         

2、静态加载&动态加载

 静态加载类:编译时加载,指的是通过new创建的对象,在编译时加载所有可能用到的类。

 动态加载类:运行时加载类。 Class.forName("类的全称")

例子:

如果在记事本上,编写一个类如下:

public class  Test{
    public static void main(String args[]){
        
        if("Word".equals(args[0])){
            Word.start();
        }
        else if("Excel".equals(args[0])){
            Excel.start();
        }
        
    }
}

通过cmd命令行,编译javac时,会报错,找不到Word类、找不到start()方法、Excel类、找不到start()方法,四个错误。

假如我们已经有了一个Word类,Word类中存在start()方法,并且已经编译过。则仍然报错找不到Excel类、找不到start()方法,两个错误。

这就造成了,本来是运行word,却因为excel报错而无法运行。

然后,我们对程序做如下修改:

1.创建一个OfficeRef接口

public interface OfficeRef{
    public void start();
}

2.创建Word类继承OfficeRef接口

public class Word implements OfficeRef{
    public void start(){
        System.out.println("word starting...");
    }
}

3.将Test类做如下修改

public class  Test{
    public static void main(String args[]){
        if("Word".equals(args[0])){
            try{
                Class c = Class.forName(args[0]);  //动态加载类,通过类类型创建Class对象(全路径)
                OfficeRef off = (OfficeRef)c.newInstance(); //根据实例创建类
                off.start();
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
}

在cmd命令下,首先编译OfficeRef,然后word,然后编译Test类,最后运行  java Test Word 发现可以成功运行

此处Word换成excel依然可以。这就是动态加载类的好处。

功能性的类使用动态加载。

 3.反射--获取方法的信息

public class ReflectClass{ 
    public static void main(String[] args) {
        Class c1 = int.class; //int的类类型
        Class c2 = String.class; 
        Class c3 = double.class;
        Class c4 = Double.class;
        Class c5 = void.class; //所有类中的元素,都含有类类型
        
        System.out.println(c1.getName());
        System.out.println(c2.getName());
    }
}
public class ClassUtil {        
    public static  void getMethodRef(Object obj){
        Class c = obj.getClass();
        c.getName();
        Method[] ms = c.getMethods(); //获取的是所有的public类型的,包括从父类中继承的方法
        Method [] mms = c.getDeclaredMethods();//获取的是所有的自己类声明的方法;
        for(int i=0;i<ms.length;i++){
            System.out.println(ms[i].getName());
            Class returnType = ms[i].getReturnType(); //返回的是返回类型的类类型
            System.out.println(returnType.getName());
            Class []paraType=ms[i].getParameterTypes(); //参数类型的类类型
            for(Class param:paraType){
                System.out.print(param.getName()+",");
            }
        }    
    }
}
public class Demo {
    public static void main(String[] args) {
        String s ="Hello";
        ClassUtil.getMethodRef(s);
    }
}

4.获取成员变量构造函数信息

成员变量也是对象,是java.lang.reflect.Filed Filed类获得了封装关于成员变量的操作

Filed fs[] =c.getFileds()

posted @ 2015-11-14 21:02  douding1828  阅读(221)  评论(0编辑  收藏  举报