Java反射(重要)

全文内容

1: 获取字节码文件对象的三种方式
2: 获取公有,私有方法,并调用构造方法,成员方法
3: 获取并调用私有成员变量
4: 如何为实例对象的成员变量赋值
5: 文末有一些注意

tea1类代码

class tea1{
    private String i;
    public int j;
    public tea1(){}
    public tea1(int j){
       this.j = j;
    }
    private tea1(String i,int j){
        this.j = j;
        this.i = i;
    }

    @Override
    public String toString() {
        return "tea1{" +
                "i='" + i + '\'' +
                ", j=" + j +
                '}';
    }
    private void q(){
        System.out.println("调用私有成员方法");
    }
}

测试类代码

package 学习.反射;

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

public class a {
    public static void main(String[] args) throws 
    	ClassNotFoundException, NoSuchMethodException, 
    		IllegalAccessException, InvocationTargetException, 
    			InstantiationException, NoSuchFieldException {
        //获取字节码文件对象的三种方式
        //一(推荐):foeName()里面是类所在的全路径
        //idea可以右键所在类,然后点击copy,然后点击copy reference,行了
        Class<?> tea1 = Class.forName("学习.反射.tea1");
       	//二:通过类对象获取字节码文件对象
        tea1 tea11 = new tea1();
        Class<?> aClass = tea11.getClass();
        //三:通过类名获取字节码文件对象
        Class<?> aClass1 = tea1.getClass();
        /*
		提前补充:
		tea1.getConstructor(),这里面的参数是字节码文件对象
		举例
		Constructor<?> constructor1 = tea1.getConstructor(int.class);
		这句意思是:返回了tea1类中的带有一个int参数的构造器,这个构造方法
		默认是公有的,私有下面会讲.
		举例:Constructor<?> constructor2 
		=tea1.getConstructor(int.class,String.class);
		意思是获取带有两个参数的构造器int与String.
		相信大家可以触类旁通
		*/
        //获取无参构造器
        Constructor<?> constructor = tea1.getConstructor();
        //获取有参构造器
        Constructor<?> constructor1 = tea1.getConstructor(int.class);
        /*
		在不使用反射机制时,私有的构造方法是在外部无法调用的,拓展一下:比
		如饿汉式,懒汉式设计模式,这两种设计模式就是将构造方法私有化了,
		可以自己去了解以下,也可以等我更新文章。
		Constructor<?> declaredConstructor = 
		tea1.getDeclaredConstructor(String.class, int.class);
		declaredConstructor.setAccessible(true);
		第一句是获取了一个私有的构造器对象,不过这个对象有锁
		第二句就是破除锁。
		*/
        //获取私有构造器
        Constructor<?> declaredConstructor = 
        	tea1.getDeclaredConstructor(String.class, int.class);
        //破除私有
        /*
        * 可以理解为公有方法在第一步找到对象就可以直接使用,而私有需要打开					
        * 私有锁,	
        * setAccessible就是打开锁
        * */
        declaredConstructor.setAccessible(true);
        /*
		可以在创建对象的时候传递参数,这个参数数量与类型要与
		上边的tea1.getConstructor(int.class)相照应,否则有些运行时会出错
		在这是使用上边获得的构造器来创建对象的过程
		为了方便大家查看,我把上边代码贴过来了,可以一一对照
		*/
        //创建对象
        //无参
        //Constructor<?> constructor = tea1.getConstructor();
        Object o = constructor.newInstance();
        //有参
		// Constructor<?> constructor1 = tea1.getConstructor(int.class);
        Object o1 = constructor1.newInstance(1);
        /*Constructor<?> declaredConstructor =
       	  		tea1.getDeclaredConstructor(String.class, int.class); */ 
        Object a = declaredConstructor.newInstance("a", 1);
        //获取方法
        //这是获取公有方法,tea1.getMethod("toString")其中toString是类中	的方法名
        Method toString = tea1.getMethod("toString");
        //这是获取私有方法
        Method declaredMethod = tea1.getDeclaredMethod("q");
        //破除私有,
        declaredMethod.setAccessible(true);
        //下面是调用方法
        //结构式:方法对象.invoke(实例对象)
        //反射,反着写(狗头)
        declaredMethod.invoke(o);
        //输出3个结果
        //使用反射机制调用方法
        System.out.println(toString.invoke(o));
        //直接输出就是默认调用toString
        System.out.println(o1);
        System.out.println(toString.invoke(a));
        //获取成员变量
        //获取公有变量
        Field j = tea1.getField("j");
        //输出a实例对象的j成员变量
        System.out.println(j.get(a));
        //私有成员变量
        Field i = tea1.getDeclaredField("i");
        //破除私有
        i.setAccessible(true);
        //输出a实例对象的成员变量
        //结构:变量对象名.get(实例对象名)
        //反射,反着写(狗头)
        System.out.println(i.get(a));
        //至此,获取构造方法的内容结束
        //获取成员变量
		


		//现在,获取实例对象,方法,变量都讲完了
		//讲解如何为实例对象的成员变量进行赋值
		//不知道大家现在能否看懂
		//获取私有成员变量
        Field j1 = tea1.getDeclaredField("j");
        //破除私有变量
        j1.setAccessible(true);
        //为成员变量赋值
        //j1是成员变量的实例化对象
        //o是上文创建的一个对象,我把代码粘贴过来了
        //Constructor<?> constructor = tea1.getConstructor();
        //Object o = constructor.newInstance();
		//结构:成员变量的实例化对象.set(类的实例化对象,对应的成员变量的值)
		//400是int,原因是:
		//Field j1 = tea1.getDeclaredField("j");
		//而j在类中是int类型,一定要类型对应
        j1.set(o,400);
        //获取并输出o对象的成员变量j的值
        System.out.println(j1.get(o));
    }
}

注意:可以按照获得私有构造器,私有方法,私有对象的函数处理公有方法,这样不会在一些未知的情况下出错。
推荐大家都使用Class.forName()来获取字节码文件对象。
谢谢大家。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值