JAVA初级(三十四),反射介绍和基本使用。反向获取Class对象

正常情况下我们获取一个对象要new XXX,然后才能操作。但有一种方法可以不用这么做就可以获取一个对象。也就是在JAVA运行期间能够动态的获取一个类的Class对象,这个Class对象能够对其进行类名,属性,构造方法,方法等的获取以及方法的调用,这么一个过程就是反射

从这里能初步了解,如果你要造一个框架给别人用.但你不知道别人的类会取什么名字。这时如果你要操作别人写的未知的类。那么反射就是一个很好的办法

1,通过反射获取类的Class对象
这样不用new来获取对象的过程也可以说是反向获取对象。这样的方法有三种
1,实例对象.getClass()
2,类名.class;
3,Class.forName(“全包名”);

//实例对象.getClass()获取类的class对象
ClassDemo classDemo = new ClassDemo();
Class classDemoClass = classDemo.getClass();
System.out.println(classDemoClass.getName());//获取类名

//类名.class获取类的class对象
Class<ClassDemo> classDemoClass1 = ClassDemo.class;

//通过Class.forName(“全包名”)获取类的class对象
Class<?> classDemo1 = Class.forName("ClassDemo");//括号内是全包名,即包名.类名

//比较一下,会发现输出的是true表示一个类只会有一个class对象
System.out.println(classDemoClass.equals(classDemoClass1));
System.out.println(classDemoClass1.equals(classDemo1));

2,通过反射类对象获取构造方法并调用
Class对象有专门用来获取构造方法的方法。它们被封装在了一个Constructor类上
getConstructors();//获取所有public的构造方法
getDeclaredConstructors();//获取所有构造方法,包括private.
getConstructor([参数类型类对象]);//获取指定的public构造方法,根据参数类型来指定
getDeclaredConstructor([参数类型类对象]);//获取指定的包括private,protected的构造方法,根据参数类型来指定
newInstance();//执行构造方法

        Class<?> classDemo = Class.forName("ClassDemo");
        //获取所有public的构造方法
        Constructor<?>[] constructors = classDemo.getConstructors();
        for (Constructor constructor: constructors) {
            System.out.println(constructor);
        }
        //获取所有构造方法(包括private,protected)
        Constructor<?>[] declaredConstructors = classDemo.getDeclaredConstructors();
        for (Constructor constructor: declaredConstructors) {
            System.out.println(constructor);
        }
        //获取指定的public构造方法,根据参数类型来指定
        Constructor<?> constructor = classDemo.getConstructor(String.class, String.class);
        System.out.println(constructor);
        //获取指定的包括private,protected的构造方法,根据参数类型来指定
        Constructor<?> declaredConstructor = classDemo.getDeclaredConstructor(String.class);
        System.out.println(declaredConstructor);
        //添加执行权限,没有这句话无法执行private方法
        declaredConstructor.setAccessible(true);
        //执行构造方法,返回一个对应的实例对象
        Object obj = declaredConstructor.newInstance("String");

3,通过反射类对象获取属性并对其赋值和取值
类对象的属性都被封装在了一个Field对象中
getFields();//获取所有public的属性,返回一个Filed数组,包括父类的public属性
getDeclaredFields();//获取所有属性,包括private.返回一个Filed数组,但只能获取自己的属性不包括父类属性
getField(String name);//根据public的属性名称来获取指定属性.返回一个Field对象,可以获取父类的public属性
getDeclaredField(String name);//根据指定属性名称获取属性,包括private,返回一个Field对象,只能获取自身属性
Field对象.set(属性对应类的实例对象,值);//可以对这个属性赋值
Field对象.get(属性对应类的实例对象);//可以取出这个属性的值

 Class<?> classDemo = Class.forName("ClassDemo");
        //获取所有public的属性
        Field[] fields = classDemo.getFields();
        for (Field field: fields) {
            System.out.println(field);
        }
        //获取所有属性,包括private,protected
        Field[] declaredFields = classDemo.getDeclaredFields();
        for (Field field: declaredFields) {
            System.out.println(field);
        }
        //获取指定的public属性,根据名称获取
        Field men = classDemo.getField("men");
        //获取指定的属性,包括private,protected
        Field name = classDemo.getDeclaredField("name");
        //创建一个对象来操作这些属性
        Object o = classDemo.newInstance();
        //获取的属性,set(对应的对象,值)方法来给这个属性赋值
        men.set(o,"男人");
        //如果是私有属性,先设置权限在操作
        name.setAccessible(true);
        name.set(o,"张三");
        //用属性.get(对应对象)来取值
        System.out.println(men.get(o));
        System.out.println(name.get(o));

4,通过反射类对象获取方法,并执行该方法
Class对象的方法都被封装在了Method类中

	Class<?> classDemo = Class.forName("ClassDemo");
        //获取所有public方法,包括Object的方法.,即父类的public方法
        Method[] methods = classDemo.getMethods();
        for (Method method: methods) {
            System.out.println(method);
        }
        //获取所有方法,包括private,但不包括Object的方法和父类的方法
        Method[] declaredMethods = classDemo.getDeclaredMethods();
        for (Method method: declaredMethods) {
            System.out.println(method);
        }
        //获取指定的public方法,根据名称和参数列表类型来指定
        Method setName = classDemo.getMethod("setName", String.class);
        Method getName = classDemo.getMethod("getName");
        System.out.println(setName.getName());
        //获取指定的方法,包括private,根据名称和参数列表类型来指定
        Method sex = classDemo.getMethod("setSex", String.class);
        System.out.println(sex.getName());
        //执行方法,使用Method对象的invoke(该方法对应的实例对象,参数值)
        Object o = classDemo.newInstance();
        setName.invoke(o,"张三");
        Object invokeResult = getName.invoke(o);
        System.out.println(invokeResult);
        //执行private方法时同样要先设置权限
        sex.setAccessible(true);
        sex.invoke(o,"男");

5,获取父类对象并对其操作
子类的Class对象.getSuperclass();//就能获取父类的Class对象
然后同样使用getFields()等方法来获取和操作父类的属性和方法。

Class<?> classDemo = Class.forName("ClassDemo");
        //用子类的Class对象来获取父类的Class对象
        Class<?> superclass = classDemo.getSuperclass();
        //通过父类的Class对象来获取属性等.
        Field[] declaredFields = superclass.getFields();
        for (Field field:declaredFields) {
            System.out.println(field.getName());
        }

其中父类的public方法和属性可以通过子类的getFields()等方法来获取和操作。

Class<?> classDemo = Class.forName("ClassDemo");
        //通过子类的这种获取所有public的方法同时可以获取父类的所有public属性和方法
        Field[] declaredFields = classDemo .getFields();
        for (Field field:declaredFields) {
            System.out.println(field.getName());//包括父类属性
        }

总结:
1,反射是什么?
反射就是JAVA在运行过程中动态的反向获取类的Class对象然后对其操作的过程
2,反射获取类对象的方法?
(1)类名.class
(2)实例对象.getClass()
(3)Class.forName(全包名)
3,如何操作类对象
记住以下几点就很容易记得操作这个对象的各种方法
(1)构造方法封装在了Constructor类上,用各种getConstructor就可以获取构造方法。它的执行方法是newInstance()
(2)普通方法封装在了Method类上,用各种getMethod()就可以获取普通方法。它的执行方法是invoke()
(3)属性被封装在了Field类上,用各种getField()就可以获取属性。它的操作方法是set()和get()
(4)获取父类用getSuperclass()方法。
这样类对象的基本操作方法就说完了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值