【java】 反射 学习笔记

java中万事万物皆对象,类也是对象,它是Class类的对象,这个对象叫做该类的类类型。

创建该类的类类型的三种方式:

//Foo的实例对象
Foo f1 = new Foo();
//法一,任何类都有一个隐含的静态成员变量class
Class c1 = Foo.class;
//法二
Class c2 = f1.getClass();
//法三
Class c3 = null;
        try {
            c3 = Class.forName("Foo");
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }

一个类只可能是Class类的一个实例对象。

对上述代码判断c1==c2,c2==c3,结果均为true。

还可以通过类的类类型创建类的实例。

try {
            Foo foo = (Foo)c1.newInstance();
        }catch (InstantiationException e){
            e.printStackTrace();
        }catch (IllegalAccessException e){
            e.printStackTrace();
        }

此时该类需要有无参构造方法。

可以通过类的类类型来获取类的信息,例如类的成员变量,成员方法:

要获取类的信息,首先要得到类的类类型。

Class c = obj.getClass();

调用getName()方法可以获取类的名字:

System.out.println("类的名称是:" + c.getName());

在java.lang.reflect.field类中封装了对成员变量的操作,该类中有两个成员方法:

getFields()方法获取的是所有public变量的信息

getDeclaredFields()方法获取的是该类自己定义的成员变量的信息(不论访问权限)

这两个方法都返回一个Field类型的数组。

对于每一个成员变量,先要得到它的类类型之后才可以获取到成员变量的类型。

Field[] fields = c.getDeclaredFields();
        for(Field fs : fields){
            //得到成员变量的类型的类类型
            Class fieldType = fs.getType();
            //得到成员变量类型的名称
            String typename = fieldType.getName();
            String name = fs.getName();
            System.out.print(typename + " ");
            System.out.println(name);//得到变量名
        }

在java.lang.reflect.method类中封装了对成员方法的操作,该类中有两个成员方法:

getMethods()方法获取的是所有public方法的信息,包括从父类继承的方法

getDeclaredMethods()方法获取的是该类自己定义的成员方法的信息(不论访问权限),不包括从父类继承的方法

这两个方法都返回一个Method类型的数组。

得到方法的类类型之后,调用getReturnType()方法可以得到它的返回值的类类型。

Class returnType = ms[i].getReturnType();
System.out.print(returnType.getName() + " ");

调用getParameterTypes()方法可以得到它的参数列表的类类型。

Class[] paramTypes = ms[i].getParameterTypes();
            for(int j = 0;j < paramTypes.length;j ++){
                System.out.print(paramTypes[j].getName() + ",");
            }
            System.out.println(")");

我们可以为类中的任一个成员方法定义一个Method对象,反射就是利用Method对象来调用该方法

try {
            //正常调用
            //a1.print(10,20);
            //方法的反射操作->用m对象来调用方法
            //二者调用的效果完全相同
            //如果方法的返回值是void,返回null,否则返回返回值的类型

            //第一个参数是方法名,后面的参数是方法的参数,有多少写多少,没有则不写
            Method m = c.getDeclaredMethod("print",int.class,int.class);
            //Object o = m.invoke(a1, new Object[]{10, 20});
            Object o = m.invoke(a1, 10, 20);

            Method m1 = c.getMethod("print", String.class, String.class);
            Object o1 = m1.invoke(a1, "hello", "world");
        }catch (Exception e){
            e.printStackTrace();
        }

猜你喜欢

转载自blog.csdn.net/qq_41279172/article/details/101177462