马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
在实际开发中,通过反射可以得到一个类的完整结构,包括类的构造方法、类的属性、类的方法,这就需要使用到java.lang.reflect包中的以下几个类:
1、Constructor:表示类中的构造方法
2、Field:表示类中的属性
3、Method:表示类中的方法
目录
1、使用反射技术获取构造器对象并使用
2、使用反射技术获取成员变量对象并使用
3、使用反射技术获取方法对象并使用
使用反射技术获取构造器对象并使用
实验类:
- public class 反射机制_2实验类 {
- private String name;
- private int age;
- private 反射机制_2实验类() {
- System.out.println("无参构造器执行!");
- }
- public 反射机制_2实验类(String name, int age) {
- System.out.println("有参构造器执行!");
- this.name = name;
- this.age = age;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- @Override
- public String toString() {
- return "反射机制_2实验类{" +
- "name='" + name + '\'' +
- ", age=" + age +
- '}';
- }
- }
复制代码 获取构造器对象:
- import org.junit.Test;
- import java.lang.reflect.Constructor;
- public class 反射机制_2构造器获取对象 {
- //1、getConstructors
- //获取全部的构造器,只能获取public修饰的构造器
- @Test
- public void getConstructors(){
- //获取类对象
- Class c=反射机制_2实验类.class;
- //提取类中的全部的构造器对象(这里只能拿public修饰的构造器)
- Constructor[] constructors=c.getConstructors();
- //遍历构造器
- for (Constructor constructor : constructors) {
- System.out.println(constructor.getName()+"\t构造器参数个数为:"+constructor.getParameterCount()+"个");
- }
- //运行结果:IT2.反射机制_2实验类 构造器参数个数为:2个
- }
- //2、getDeclaredConstructors
- //获取全部的构造器:只要你敢写,这里就能拿到,无所谓权限是否可及
- @Test
- public void getDeclaredConstructors(){
- //获取类对象
- Class c=反射机制_2实验类.class;
- //提取类中的全部的构造器对象
- Constructor[] constructors=c.getDeclaredConstructors();
- //遍历构造器
- for (Constructor constructor : constructors) {
- System.out.println(constructor.getName()+"\t构造器参数个数为:"+constructor.getParameterCount()+"个");
- }
- //运行结果:
- // IT2.反射机制_2实验类 构造器参数个数为:0个
- // IT2.反射机制_2实验类 构造器参数个数为:2个
- }
- //3、getConstructor
- //获取某个构造器:只能拿Public修饰的某个构造器
- @Test
- public void getConstructor() throws Exception {
- //获取类对象
- Class c=反射机制_2实验类.class;
- //定位单个构造器对象(按照参数,这里定位的是有参的构造器)
- Constructor cons=c.getConstructor(String.class,int.class);
- // Constructor cons=c.getConstructor();//如果获取无参构造器,但因为我设置的是private私有的,权限不足无法获取,便会报错
- System.out.println(cons.getName()+"\t构造器参数个数为:"+cons.getParameterCount()+"个");
- //运行结果:IT2.反射机制_2实验类 构造器参数个数为:2个
- }
- //4、getDeclaredConstructor
- //获取某个构造器:只要你敢写,这里就能拿到,无所谓权限是否可及
- //一般是用这个,什么都可以获取,并且是根据自己需要什么而获取
- @Test
- public void getDeclaredConstructor() throws Exception {
- //获取类对象
- Class c=反射机制_2实验类.class;
- //定位单个构造器对象(按照参数,这里定位的是有参的构造器)
- Constructor cons=c.getDeclaredConstructor(String.class,int.class);
- System.out.println(cons.getName()+"\t构造器参数个数为:"+cons.getParameterCount()+"个");
- //运行结果:IT2.反射机制_2实验类 构造器参数个数为:2个
- //获取类对象
- Class c2=反射机制_2实验类.class;
- //定位单个构造器对象(按照参数定位无参构造器)
- Constructor cons2=c2.getDeclaredConstructor();
- System.out.println(cons2.getName()+"\t构造器参数个数为:"+cons2.getParameterCount()+"个");
- //运行结果:IT2.反射机制_2实验类 构造器参数个数为:0个
- }
- }
复制代码 Class在开发中最常见的用法就是将Class类对象实例化为自定义类的对象,即可通过一个给定的字符串(类的全限定类名)实例化一个本类的对象。将Class对象实例化为本类对象时,可以通过无参构造完成,也可以通过有参构造完成。
创建对象:
- import org.junit.Test;
- import java.lang.reflect.Constructor;
- //反射可以破坏封装性,私有的也可以执行了
- public class 反射机制_2创建对象 {
- @Test
- public void getDeclaredConstructor() throws Exception {
- //获取类对象
- Class c=反射机制_2实验类.class;
- //定位单个构造器对象(按照参数,这里定位的是有参的构造器)
- Constructor cons=c.getDeclaredConstructor(String.class,int.class);
- System.out.println(cons.getName()+"\t构造器参数个数为:"+cons.getParameterCount()+"个");
- 反射机制_2实验类 s1= (反射机制_2实验类) cons.newInstance("狗蛋",18);
- System.out.println(s1);
- System.out.println();
- //获取类对象
- Class c2=反射机制_2实验类.class;
- //定位单个构造器对象(按照参数定位无参构造器)
- Constructor cons2=c2.getDeclaredConstructor();
- System.out.println(cons2.getName()+"\t构造器参数个数为:"+cons2.getParameterCount()+"个");
- //如果遇到了私有的构造器,可以暴力反射
- cons2.setAccessible(true);//权限打开(只是这一次有效,并不是一直打开)
- 反射机制_2实验类 s2= (反射机制_2实验类) cons2.newInstance();
- System.out.println(s2);
- //运行结果:
- //IT2.反射机制_2实验类 构造器参数个数为:2个
- //有参构造器执行!
- //反射机制_2实验类{name='狗蛋', age=18}
- //
- //IT2.反射机制_2实验类 构造器参数个数为:0个
- //无参构造器执行!
- //反射机制_2实验类{name='null', age=0}
- }
- }
复制代码 使用反射技术获取成员变量对象并使用
实验类:
- public class 反射机制_2实验类2 {
- private String name;
- private int age;
- public static String schoolName;
- public static final String Name="遇安";
- public 反射机制_2实验类2() {
- System.out.println("无参构造器执行!");
- }
- public 反射机制_2实验类2(String name, int age) {
- System.out.println("有参构造器执行!");
- this.name = name;
- this.age = age;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public static String getSchoolName() {
- return schoolName;
- }
- public static void setSchoolName(String schoolName) {
- 反射机制_2实验类2.schoolName = schoolName;
- }
- @Override
- public String toString() {
- return "反射机制_2实验类2{" +
- "name='" + name + '\'' +
- ", age=" + age +
- '}';
- }
- }
复制代码 获取成员变量:
在反射操作中可以获取一个类中的全部属性,但是类中的属性包括两部分,即从父类继承的属性和本类定义的属性。因此,在获取类的属性时也有以下两种不同的方式:
1、获取实现的接口或父类中的公共属性:public Field [] getFields throws SecurityException
2、获取本类中的全部属性:public Field [] getDeclaredFields throws Exception
上述两种方法返回的都是Field数组,每一个Field对象表示类中的一个属性。如果要获取属性中的详细信息,就需要调用Field类的方法。
- import org.junit.Test;
- import java.lang.reflect.Field;
- public class 反射机制_2获取成员变量 {
- //1、获取全部的成员变量
- // Field[] getDeclaredFields
- //获得所有的成员变量对应的Field对象,只要申明了就可以得到
- @Test
- public void getDeclaredFields(){
- //定位Class对象
- Class c=反射机制_2实验类2.class;
- //定位全部成员变量
- Field [] fields=c.getDeclaredFields();
- //遍历获取,常量也会被当做成员变量
- for (Field field : fields) {
- System.out.println(field.getName()+"的类型是:"+field.getType());
- }
- }
- //2、获取某个成员变量对象
- //Field getDeclaredField(String name)
- @Test
- public void getDeclaredField() throws Exception {
- //定位Class对象
- Class c=反射机制_2实验类2.class;
- //根据名称定位某个成员变量
- Field f=c.getDeclaredField("age");
- System.out.println(f);
- System.out.println(f.getName()+"的类型是:"+f.getType());
- }
- }
复制代码 运行结果:
Test1、
name的类型是:class java.lang.String
age的类型是:int
schoolName的类型是:class java.lang.String
COUNTTRY的类型是:class java.lang.String
Test2、
private int IT2.反射机制_2实验类2.age
age的类型是:int
获取了成员变量有什么用呢?
- import org.junit.Test;
- import java.lang.reflect.Field;
- public class 反射机制_2获取成员变量 {
- //获取了成员变量有什么用呢?
- @Test
- public void demo() throws Exception {
- //反射第一步获取Class对象
- Class c=反射机制_2实验类2.class;
- //提取某个成员变量
- Field f=c.getDeclaredField("age");
- f.setAccessible(true);//因为我的age成员变量是用private修饰的,所以需要暴力打开权限
- //作用一:赋值
- 反射机制_2实验类2 s=new 反射机制_2实验类2();
- f.set(s,18);//s.setAge(18);
- System.out.println(s);
- //运行结果:
- // 无参构造器执行!
- //反射机制_2实验类2{name='null', age=18}这里可以看出,成员变量被赋值成功
- //作用二:取值
- int age = (int) f.get(s);
- System.out.println(age);//18
- }
- }
复制代码 使用反射技术获取方法对象并使用
实验类:
- public class 反射机制_2实验类3 {
- private String name;
- public 反射机制_2实验类3() {
- }
- public 反射机制_2实验类3(String name) {
- this.name = name;
- }
- public void run(){
- System.out.println("跑起来了。。");
- }
- private void eat(){
- System.out.println("累了,该吃饭了。。");
- }
- private String eat(String name){
- System.out.println("那就浅吃一下"+name+"吧");
- return "针不戳";
- }
- public static void ind(){
- System.out.println("欢迎来到遇安的博客!");
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- }
复制代码 获取成员方法:
- import org.junit.Test;
- import java.lang.reflect.Method;
- public class 反射机制_2获取成员方法 {
- //获得类中的所有成员方法对象
- @Test
- public void getDeclaredMethods(){
- //获取类对象
- Class c=反射机制_2实验类3.class;
- //提取全部方法,包括私有的
- Method [] methods=c.getDeclaredMethods();
- //遍历全部方法
- for (Method method : methods) {
- System.out.println(method.getName()+"返回值类型:"+method.getReturnType()+"参数个数:"+method.getParameterCount());
- }
- }
- //提取某个方法对象
- @Test
- public void getDeclaredMethod() throws Exception {
- //获取类对象
- Class c=反射机制_2实验类3.class;
- //提取单个方法对象
- Method m1=c.getDeclaredMethod("eat");
- Method m2=c.getDeclaredMethod("eat",String.class);
- //暴力打开权限
- m1.setAccessible(true);
- m2.setAccessible(true);
- //触发方法的执行
- 反射机制_2实验类3 s=new 反射机制_2实验类3();
- //注意:如果方法是没有结果返回的,那么返回的是Null
- Object result =m1.invoke(s);
- System.out.println(result);
- Object result2=m2.invoke(s,"海鲜大餐");
- System.out.println(result2);
- }
- }
复制代码 运行结果:
累了,该吃饭了。。
null
那就浅吃一下海鲜大餐吧
针不戳
来源:https://blog.csdn.net/qq_62731133/article/details/125089941
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |