反射

什么是反射

reflection(反射)

Class类是一个管理反射的类

一个类只有一个Class对象

一个类被加载后都会被封装在一个Class对象中

获取字节码的三个方法

 /*第一种方式通过地址获取反射*/
        Class c1 = Class.forName("Student");
        /*通过类名获得*/
        Class<Student> c2 = Student.class;
        /*通过对象名获取*/
        Student person= new Student();
        Class c3= person.getClass();
        /*一个对象只能有一个Class*/
        System.out.println(c1.hashCode());
        System.out.println(c2.hashCode());
        System.out.println(c3.hashCode());

什么时候类会初始化

类的加载:将class文件字节码内容加载到内存中,并将这些静态数据转化成方法区的运行时数据结构,然后生成一个代表这个类的java,long,Class对象。

主动引用

当new子类对象的时候父类会被初始化,子类也会初始化

反射引用子类,父类和子类都要初始化

被动引用(不会产生初始化)

子类去调用父类的静态方法和变量子类不会被初始化

数组也不会产生初始化

调用常量不会初始化子类和父类

反射的操作方法

newInstance()用无参的构造器来new对象

Class demo1 = Class.forName("Demo1")
Demo1 c1 =(Demo1) demo1.newInstance();

getDeclaredConstructor()通过有参的方法来new对象

Class demo1 = Class.forName("Demo1")
 Constructor Constructor = demo1.getDeclaredConstructor(int.class, String.class, Demo2.class);
 Demo1 c2 = (Demo1)Constructor.newInstance(12,"云边",new Demo2("小卖部"));
    

getDeclaredMethod获取方法

        Class demo1 = Class.forName("Demo1");
        Demo1 c1 =(Demo1) demo1.newInstance();
        Method setName = demo1.getDeclaredMethod("setName", String.class);

invoke(那个对象,赋值)打开方法权限

setName.invoke(c1,null);

getDeclaredField修改属性

  Field name2 = demo1.getDeclaredField("name");

setAccessible(true);关闭安全检查

  Field name2 = demo1.getDeclaredField("name");
        name2.setAccessible(true);
        name2.set(c2,"梦");
        

set赋值

name2.set(c2,"梦");

通过反射去建对象和调方法


import java.lang.reflect.Method;

import java.util.ArrayList;

 

/*

 * 通过反射越过泛型检查

 * 

 * 例如:有一个String泛型的集合,怎样能向这个集合中添加一个Integer类型的值?

 */

public class Demo {

	public static void main(String[] args) throws Exception{

		ArrayList<String> strList = new ArrayList<>();

		strList.add("aaa");

		strList.add("bbb");

		

	//	strList.add(100);

		//获取ArrayList的Class对象,反向的调用add()方法,添加数据

		Class listClass = strList.getClass(); //得到 strList 对象的字节码 对象

		//获取add()方法

		Method m = listClass.getMethod("add", Object.class);

		//调用add()方法

		m.invoke(strList, 100);

		

		//遍历集合

		for(Object obj : strList){

			System.out.println(obj);

		}

	}

}

通过反射无参构造和有产构造

     Class c1 = Class.forName("Demo1");/*获取字节码c1*/
       Constructor Constructor = c1.getDeclaredConstructor(int.class,String.class,Demo2.class);/*根据c1去调用构造器*/
       Demo1 c2=(Demo1) Constructor.newInstance(15, "王梦", new Demo2("云边有个小卖部"));/*new出对象叫c2*/
           System.out.println(c2);
        Method getDemo2 = c1.getDeclaredMethod("getDemo2");/*通过c1去调方法*/
        Method setName = c1.getDeclaredMethod("setName", String.class);/*通过字节码c1去获取setname的方法*/
               /*invoke激活的意思*/
        setName.invoke(c2,"wang");/*激活set方法通过对象c2给里面的setname赋值*/
        System.out.println(c2.getName()+"获去年纪");
        System.out.println(getDemo2.getName());

        System.out.println(  c2.getDemo2().getName());
        System.out.println("===============================================");
                        /*通过反射去操作属性*/
        Demo1 demo1 =(Demo1) c1.newInstance();/*通过c1去获取无参的构造方法*/
        System.out.println(demo1);
        Field name = c1.getDeclaredField("name");/*通过方法获取声明字段*/
        name.setAccessible(true);/*关闭安全检查*/
        name.set(demo1,"孟");/*通过set跟demo1对象的name赋值*/
        System.out.println(demo1.getName());


    }

自我总结

我觉得反射就是通过反射获取唯一字节码对象,通过字节码对象去获取方法,泛型,属性,父类,变量,放入通过字节码对象new的对象中,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值