JAVA反射

一、类加载(将class文件读入内存,创建一个java.lang.Class对象)

当程序还未使用某个类的时候,如果该类没有被加载到内存中,则系统会通过类的加载、类的连接、类得初始化三个步骤对类进行初始化,如果不要出现意外,JVM虚拟机会连续执行这三个操作,所以会把这三个步骤统称为类加载或类的初始化。

1、类加载时机

二、反射

反射机制:在运行时去获取一个类的变量或方法信息。然后通过获取到的信息来创建对象,调用方法的一种机制。这种动态性,极大增强了程序的灵活性,程序不用再编译期就完成确定,运行期仍可以拓展。

通过Class类(字节码文件对象)使用Student或者Teacher类中的成员变量、方法等,就是反射。内存中只存在一个相同类的字节码对象。

1、获取Class对象的三种方法

            //1、通过类class属性
		Class<Student> stu = Student.class;
		
		//2、对象的getClass方法
		Student student = new Student();
		Class<? extends Student> stu2 = student.getClass();
		System.out.println(stu == stu2);  //true 同一个类内存只有一个字节码对象
		
		//3、Class的静态方法forName
		Class<?> stu3 = Class.forName("com.example.demo.practice.Student");
		System.out.println(stu == stu3);

2、反射获取构造方法、创建实例对象

        //获取所有公共的构造方法
		Constructor<?>[] cons = stu.getConstructors();
		//获取所有构造方法
		Constructor<?>[] consAll = stu.getDeclaredConstructors();
		
		//反射获取无参构造方法,创建对象
		Constructor<Student> con = stu.getConstructor();
		Student student2 = con.newInstance();
		System.out.println(student2);
		//反射获取有参构造方法,有参创建对象
		Constructor<Student> con2 =                     stu.getConstructor(String.class,int.class,String.class);
		Student student3 = con2.newInstance("xin",22,"beijng");
		System.out.println(student3);
		
		//反射获取私有的构造方法创建对象
		Constructor<Student> conprivate = stu.getDeclaredConstructor(String.class);
		//私有的构造方法获取没有问题,创建实例对象需要设置暴力反射
		conprivate.setAccessible(true); //true 取消访问检查
		Student stupri = conprivate.newInstance("wang");
		System.out.println(stupri);

3、反射获取私有变量以及赋值

        //获取属性
		Field[] fields = stu3.getFields(); //获取所有公共的
		Field[] fields2 = stu3.getDeclaredFields(); //获取所有的
		//Field address = stu3.getField("address"); //获取指定名公共的
		//Field name = stu3.getDeclaredField("name"); //获取指定名的
		
		//为属性赋值
		Constructor<?> constru = stu3.getConstructor();
		Object obj = constru.newInstance();
		Field address = stu3.getField("address"); //获取指定名公共的
		Field name = stu3.getDeclaredField("name"); //获取指定名的
		name.setAccessible(true);//name是private
		name.set(obj, "xincm");
		address.set(obj, "neimeng");
		System.out.println(obj.toString());

4、反射获取成员方法

        //获取方法
		Method[] methods = stu3.getMethods();
		Method[] methods2 = stu3.getDeclaredMethods();
		//使用方法
		Method method = stu3.getMethod("method1");
		Constructor<?> constru = stu3.getConstructor();
		Object obj = constru.newInstance();
		method.invoke(obj);
		//带参数、返回值方法
		Method m2 = stu3.getMethod("method3", String.class);
		Object res = m2.invoke(obj, "哈哈");
		//private的方法
		Method m3 = stu3.getDeclaredMethod("method2");
		m3.setAccessible(true);
		m3.invoke(obj);

5、反射越过泛型检查:向一个泛型为Integer的list中添加字符串 

实现关键、因为集合add方法接收参数就是Object类型,本身集合不存在泛型,泛型只是一种规范。在jvm编译的时候语法糖就做了反省擦拭操作

        List<Integer> list = new ArrayList<Integer>();
        Class<? extends List> listclass = list.getClass();
        Method add = listclass.getDeclaredMethod("add", Object.class);
        add.invoke(list, "str");
        System.out.println(list);

6、配置文件方法执行方法

        Properties prop = new Properties();
		FileReader file = new FileReader("D:\\Users\\sts-workspace-success\\querydsl-jpa\\src\\main\\java\\com\\example\\demo\\practice\\properties.txt");
		prop.load(file);
		file.close();
		String className = (String) prop.get("className");
		String methodName = (String) prop.get("methodName");
		Class<?> stud = Class.forName(className);
		Method meth = stud.getDeclaredMethod(methodName);
		Constructor<?> construc = stud.getConstructor();
		Object stunew = construc.newInstance();
		meth.invoke(stunew);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值