首页 > 编程语言 >java高级之反射

java高级之反射

时间:2023-08-10 20:46:16浏览次数:36  
标签:aClass 本类 java 反射 对象 高级 Class 获取 xw

1.理解反射:

【其就是在运行时,它是把类中成员抽取为其他类对象的过程】

2.获取反射Class的三种方式:

【获取之前首先要创建一个类对象,这里就叫做 xw.Class

其一:

通过Class.forName的方式获取:

Class<?> aClass = Class.forName("com.ssm.entity.fanshe.xw");

其二:

通过类名.class 方式获取:

Class<xw> xwClass = xw.class;

其三:

通过对象.getClass();方式获取:

xw xw = new xw();
Class<? extends com.ssm.entity.fanshe.xw> aClass2 = xw.getClass();

3.通过反射类获取对象

【这里我们就直接用第一种方式获取对象】

【注:通过Class类对象,调用newInstance()】

//通过反射字解码获取第一种方式
Class<?> aClass = Class.forName("com.ssm.entity.fanshe.xw");
//通过反射获取类对象,其他两种方式以此类推
xw o = (xw) aClass.newInstance();
System.out.println(o);

4.获取反射类中的属性成员对象

【还是以第一种方式或取对象】

【这里通过 getDeclaredFields() 的方法可以获取本类中所有的属性成员对象(包括公有、私有)】

//通过反射字解码获取第一种方式
Class<?> aClass = Class.forName("com.ssm.entity.fanshe.xw");
//通过反射获取类对象,其他两种方式以此类推
xw o = (xw) aClass.newInstance();
System.out.println(o);

//通过反射过去类属性对象,其返回的是一个数组
//获取本来中所有的类属性对象
Field[] declaredFields = aClass.getDeclaredFields();
for (Field jk:declaredFields) {
    System.out.println("我可以获取到本类中所有的类属性:"+jk);
}

【这里通过 getFields() 的方法可以获取本类以及父类中的公有属性成员对象(注:不包括私有)

//获取本类中所有的公有的类属性对象(包括继承的父类公有类属性)
Field[] fields = aClass.getFields();
for (Field jk2:fields) {
    System.out.println("获取的是所有公共类属性:"+jk2);
}

【这里通过 getDeclaredField("age") 的方法可以获取本类中指定的单个属性成员对象】

//获取本类中指定的单个类属性
Field age = aClass.getDeclaredField("age");
System.out.println("获取的是指定的单个类属性:"+age);

 

5.Field类中具有的常用方法

5.1 setAccessible(true):设置允许访问私有属性

这里咱们首先通过反射的方式为属性成员对象设置参数

在此之前我们所获取的成员对象都是空值

Class<?> aClass = Class.forName("com.ssm.entity.fanshe.xw");
xw o = (xw) aClass.newInstance();
//通过反射来set成员属性值
Field ages = aClass.getDeclaredField("age");
        ages.set(o,66);
        System.out.println("通过反射设置的属性:"+o);

这里打印结果肯定会报错:
Exception in thread "main" java.lang.IllegalAccessException: Class com.ssm.entity.fanshe.demo1 can not access a member of class com.ssm.entity.fanshe.xw with modifiers "private"
	at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
	at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296)
	at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:288)
	at java.lang.reflect.Field.set(Field.java:761)
	at com.ssm.entity.fanshe.demo1.main(demo1.java:33)

 报错的原因是因为咱们设置的成员对象如果是私有的,它不允许访问,【非法访问 】

 这里只需要加上 变量.setAccessible(true); 即可访问私有成员对象即:【授权】

//通过反射设置set属性
Field ages = aClass.getDeclaredField("age");
ages.setAccessible(true);
ages.set(o,66);
System.out.println("通过反射设置的属性:"+o);

打印结果为:

通过反射设置的属性:xw{name = null, age = 66, hobber = null, higeh = null}

5.2 getAnnotation(注解.class):获取属性上的注解对象

这里咱们首先肯定要去自定义一个注解:并且在其中定义一个属性,以便演示 getAnnotation(注解.class)

@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.TYPE})
public @interface Myzhu {
    public String value();
}

【 如果不清楚怎么自定义注解,可以阅读我上一篇文章写的 java高级之注解

 自定义后,加在类上

随后其直接通过 getAnnotation(注解.class) 就可以获取到注解属性

//通过反射获取注解对象
Myzhu annotation = aClass.getAnnotation(Myzhu.class);
System.out.println(annotation);

 

6.获取方法类对象

6.1 getDeclaredMethods()

通过 getDeclaredMethods() 方法可以获取本类中所有的方法类对象(包括公有、私有、get、set方法)

Class<?> aClass = Class.forName("com.ssm.entity.fanshe.xw");
xw o = (xw) aClass.newInstance();
//通过反射获取本类中所有的方法类对象(包括公有、私有、get、set方法)
Method[] declaredMethods = aClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
    System.out.println("获取的是本类中所有的方法"+declaredMethod);
}

 6.2 getDeclaredMethod()

通过 getDeclaredMethod() 方法可以获取本类中指定的方法类对象

 * 值得注意的是,指定获取单个方法类对象需要填写 (String name,Class<?>... param...) 等可变参数

 eg1:

Class<?> aClass = Class.forName("com.ssm.entity.fanshe.xw");
xw o = (xw) aClass.newInstance();
//通过反射获取本类中指定的方法类对象
Method xw01 = aClass.getDeclaredMethod("xw01");
Object invoke = xw01.invoke(o);
System.out.println(invoke);
System.out.println("通过反射获取本类中指定的方法类对象:"+xw01);

 eg2:

//增加可变参数演示
Method xw02 = aClass.getDeclaredMethod("xw02",Integer.class);
xw02.invoke(o,666);


类中方法:
   public String xw02(Integer xw){
        System.out.println("----xw02-----");
        return "返回了公有方法xw02";
    }

如果要指定获取私有方法,那就多添加一个 setAccessible(true);

Class<?> aClass = Class.forName("com.ssm.entity.fanshe.xw");
xw o = (xw) aClass.newInstance();
Method xw03 = aClass.getDeclaredMethod("xw03", Integer.class);
xw03.setAccessible(true);
xw03.invoke(o,555);

【*类中方法中参数定义的什么数据类型,那么使用反射获取类中指定的方法类对象时,可变参数就填什么数据类型】

6.3 getMethods()

//通过反射获取本类及父辈中的所有方法(真的是指所有,本类及父辈的方法)
Method[] methods = aClass.getMethods();
for (Method method : methods) {
    System.out.println("通过反射获取本类及父辈中的所有方法:"+method);
}

 

7.获取构造对象

7.1 getConstructors()

Class<?> aClass = Class.forName("com.ssm.entity.fanshe.xw");
xw o = (xw) aClass.newInstance();
//通过反射获取本类中所有的构造对象
Constructor<?>[] constructors = aClass.getConstructors();
for (Constructor<?> constructor : constructors) {
    System.out.println("通过反射获取本类中所有的构造对象:"+constructor);
}

7.2 getConstructors()

【值得注意的是,这个方法与之前的不同,它只能获取本类中所有的公共构造对象,不再是可以获取本类以及父类的构造对象】

Class<?> aClass = Class.forName("com.ssm.entity.fanshe.xw");
xw o = (xw) aClass.newInstance();
//通过反射获取本类中所有的公共构造对象
Constructor<?>[] constructorss = aClass.getConstructors();
for (Constructor<?> constructor : constructorss) {
    System.out.println("通过反射获取本类中所有的公共构造对象:"+constructor);
}

7.3 Constructor类中常用的方法

7.3.1 getDeclaredConstructor() 指定获取无参构造对象

//只获取无参构造对象
Constructor<?> declaredConstructor = aClass.getDeclaredConstructor();
System.out.println("只获取无参构造对象:"+declaredConstructor);

7.3.2 getDeclaredConstructor(String name,Class<?>... param...) 指定获取私有有参构造对象

//指定获取有参构造对象
Class<jk> jkClass = jk.class;
Constructor<com.ssm.entity.fanshe.jk> declaredConstructor1 = jkClass.getDeclaredConstructor(String.class);
//获取私有构造对象,这里依然要授权,又称暴力反射
declaredConstructor1.setAccessible(true);
com.ssm.entity.fanshe.jk NineLimit = declaredConstructor1.newInstance("取九极致之术");
System.out.println(NineLimit);

打印结果:
jk{name = 取九极致之术}

class文件:
class jk{
    private String name;

    //公有无参
    public jk() {
    }

    //公有有参
    public jk(String name) {
        this.name = name;
    }

    //私有有参
    private void jk(String name){
        this.name = name;
    }
   }

以上便是java高级反射的内容,如有漏缺,请在下方评论区中留言,我会及时补充

 

标签:aClass,本类,java,反射,对象,高级,Class,获取,xw
From: https://www.cnblogs.com/9--1/p/17621192.html

相关文章

  • 在Java中操作Redis_Spring Data Redis使用方式_操作字符串类型的数据
        ......
  • 高级Java程序员值得拥有的10本书
    Java是时下最流行的编程语言之一。市面上也出现了适合初学者的大量书籍。但是对于那些在Java编程上淫浸多时的开发人员而言,这些书的内容未免显得过于简单和冗余了。那些适合初学者的书籍看着真想打瞌睡,有木有。想找高级点的Java书籍吧,又不知道哪些适合自己。别急,雪中送炭的来了:下面......
  • 每日汇报 第七周第四天 JAVA开学试题&pta
    今日学习:JAVA试题完成了主界面框架,使用while循环和switch语句实现了界面选项跳转功能,把ScoreInformation类完成了,之后就差把三个功能完善。明日计划:JAVA考试题,PTA遇到困难:JAVA怎么搞输出居中对齐啊,直接/t输出得了......
  • 在Java中操作Redis_Spring Data Redis使用方式_环境搭建
        ......
  • 在Java中操作Redis_Spring Data Redis使用方式_操作步骤说明
        ......
  • openGauss学习笔记-36 openGauss 高级数据管理-TRUNCATE TABLE语句
    openGauss学习笔记-36openGauss高级数据管理-TRUNCATETABLE语句清理表数据,TRUNCATETABLE用于删除表的数据,但不删除表结构。也可以用DROPTABLE删除表,但是这个命令会连表的结构一起删除,如果想插入数据,需要重新建立这张表。它和在目标表上进行无条件的DELETE有同样的效果,但由于......
  • javascript学习二
     文献1ECMAScript基础2对象基础javascript到底是基于对象还是面向对象?使用预定义的对象:创建新对象:继承机制3浏览器中的javascript3.1用<script></script>标签,将javascript引入html3.2Svg3.3BOMBrowserObejctModel4DOM基础关于sax和dom的区别:DOM的常识CoreDOM:HTMLDOMDOM一......
  • java多线程:死锁
    一、死锁的定义   多线程以及多进程改善了系统资源的利用率并提高了系统的处理能力。然而,并发执行也带来了新的问题——死锁。所谓死锁是指多个线程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程都将无法向前推进。   所谓死锁是指两个或两个以上的线程在......
  • JavaScript访问者模式:优雅地遍历对象
    JavaScript访问者模式JavaScript中的访问者模式是一种优雅的设计模式,它可以帮助我们遍历对象并执行特定操作。在本文中,我们将介绍访问者模式的概念、实现方式以及一个简单的示例。什么是访问者模式?访问者模式是一种行为型设计模式,它允许我们在不改变对象结构的情况下,定义新的操......
  • java中table遍历td js遍历table中的tr
    一、获取每一个tr1、通过table的id获取id="tables"获取第一行tr,索引从0开始,用eq(),方法里面的索引可以手动更换,如第二行就是1,也可以循环tr,eq里面就是循环变量$("#tablestr").eq(0);//遍历每一行for(vari=0;i<$("#tablestr").length;i++){ $("#tablestr").eq(i);......