11.Java反射机制

0.1java反射机制概述

        反射被视为动态语言的关键,反射机制允许程序在运行期借助反射API取得类的内部信息,并能直接操作对象的内部属性及方法。

        反射相关的主要API:

                java.lang.Class:代表一个类

                java.lang.reflect.Method:代表类的方法

                java.lang.reflect.Field:代表类的成员变量

                java.lang.reflect.Constructor:代表类的构造器

        不使用反射,对于Person类的操作:

//1.创建Person类的对象
Person p1=new Person("Tom",12)
//2.通过对象,调用其内部的属性、方法
p1.age=10;
pl.show()
//在Person类外部,不可以通过Person类的对象调用其内部私有结构

        使用反射之后,对于Person类的操作:

Class clazz=Person.class;
//1.通过反射创建Person类的对象
Constructor cons=class.getConstructor(String.class,int.class); //--------------
Object obj=cons.newInstance("Tom",12); //Object本质上还是Person
Person p=(Person) obj;

//2.通过反射,调用对象指定的属性、方法
  //调属性
Field age=clazz.getDeclaredField("age"); //age是属性名 ------------------
age.set(p,10);
  //调方法
Method show=clazz.getDeclaredMethod("show"); //show是方法名 --------------
show.invoke(p);

//通过反射,可以调用Person类的私有结构。私有构造器、方法、属性
    //私有构造器
Constructor cons1=clazz.getDeclaredConstructor(String.class); //------------------
cons1.setAccessible(true);
Object obj1=cons1.newInstance("jerry");
Person p1=(Person)obj1;

    //私有属性
Field name=clazz.getDeclaredField("name"); //属性名 --------------------
name.setAccessible(true);
name.set(p1,"HanMeimei");

    //私有方法
Method showNation=clazz.getDeclaredMethod("showNation",String.class); //方法名,第一个参数是对应的类型 --------------
showNation.setAccessible(true);
String nation=(String)showNation.invoke(p1,"中国"); nation就是该Person类的showNation()的返回值

0.2理解Class类并获取Class实例

        1.类的加载过程:

                (1)程序经过javac.exe命令以后,会生成一个或多个字节码文件(.class结尾)。接着我们使用java.exe命令对某个字节码文件进行解释运行。相当于将某个字节码文件加载到内存中。此过程就称为类的加载。

                (2)加载到内存中的类,我们就称为运行时类,此运行时类,就作为Class的一个实例。我们可以通过不同的方式来获取此运行时类

        2.获取Cass实例的4种方式

                方式一:通过运行时类的class属性

Class<Person> c1=Person.class;

                方式二:通过运行时类对象的getClass()

Person p1=new Person();
Class c2=p1.getClass(); //所有对象都有这个方法,因为这个方法是Object的

                方式三:调用Class的forName(String classPath)

Class c3=Class.forName("com.atguigu.java.Person");

                方式四:使用当前类的加载器ClassLoader

ClassLoader classLoader=当前类.class.getClassLoader();
Class c4=classLoader.loadClass("com.atguigu.java.Person");

0.3创建运行时类的对象

        使用newInstance():调用此方法,会创建对应的运行时类的对象,内部调用无参构造器,该构造器不能是私有的,通常为public

Class lazz = Person.class;
Person obj = (Person)clazz.newInstance();

         说明:在javabean中要求提供一个public的无参构造器。原因:

                1.便于通过反射,创建运行时类的对象

                2.便于子类实例化时,会默认调用父类的无参构造器

0.4调用运行时类的指定结构

        1.调用运行时类的属性(getField()、getDeclaredField())

Class clazz=Person.class;
Person p=(Person)clazz.newInstance();
Field id=clazz.getField("id"); //id属性名,该方法获取的属性必须为public
Field age=clazz.getDeclaredField("age");//age属性名,该方法可以获取私有的属性
id.setAccessible(true); //表示当前属性是可访问的。set私有属性前必须使用该方法
id.set(p,1001); //设置id的值。参数1:要设置哪个对象的id属性;参数2:将此id属性值设置为多少。对于静态属性,参数1就为Person.class或null
id.get(p); //获取id的值。参数1:获取哪个对象的id属性

        2.调用运行时类的方法(getDeclaredMethod())

Class clazz=Person.class;
Person p=(Person)clazz.newInstance();
Method show=clazz.getDeclaredMethod("show",String.class);//show方法名,参数2指明获取的方法参数形参列表。可以获取私有方法
show.setAccessible(true); //表示当前方法是可访问的。执行私有方法前必须使用该方法
Object obj=show.invoke(p,"Tom"); //执行方法。参数1:执行哪个对象的show方法,参数2:根据上面的形参列表类型赋值。invoke()的返回值即为show()方法的返回值,可以强转
//如果invoke()要执行的是静态方法,那么参数就为Person.class或null

        3.调用运行时类的构造器

Class clazz=Person.class;
Constructor constructor=clazz.getDeclaredConstructor(String.class); //形参列表
constructor.setAccessible(true); //表示当前构造器是可访问的。执行私有构造器前必须使用该方法
Person per=(Person)constructor.newInstance("Tom");//根据上面的形参列表赋值
//或
Person p=(Person)clazz.newInstance(); //内部会调用无参构造器
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值