【注解和反射】获取类运行时结构

这篇具有很好参考价值的文章主要介绍了【注解和反射】获取类运行时结构。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

继上一篇博客【注解和反射】类加载器-CSDN博客

【注解和反射】获取类运行时结构,java,java,开发语言,intellij-idea,class

目录

七、获取类运行时结构

测试

getFields()和getDeclaredFields()

getMethods()和getDeclaredMethods()


七、获取类运行时结构

获取类运行时结构通常指的是在Java等面向对象编程语言中,使用反射(Reflection)机制来检查类、接口、字段(Field)和方法(Method)等程序元素的能力。这种能力允许你在运行时动态地获取类的信息,并且可以调用类的方法、改变字段的值等。

在Java中,获取类运行时结构主要包括以下几个方面:

  1. 获取Class对象: 要获取类的运行时结构,首先需要获取代表该类的Class对象。这可以通过多种方式实现,例如使用.class语法、Class.forName()方法或通过对象的getClass()方法。

  2. 获取类的名称: 通过Class对象的getName()方法可以获取类的全限定名(包括包名)。

  3. 获取类的修饰符: 使用getModifiers()方法可以获取类的修饰符(如publicabstractfinal等),通常与Modifier.toString()方法结合使用以获取可读的修饰符字符串。

  4. 获取类的父类和实现的接口: 通过getSuperclass()方法可以获取类的直接父类,而getInterfaces()方法则返回当前类实现的接口数组。

  5. 获取类的字段: 使用getDeclaredFields()方法可以获取类中声明的所有字段,无论访问权限如何。而getFields()方法仅返回public字段。

  6. 获取类的方法: 类似地,getDeclaredMethods()方法返回类中声明的所有方法,而getMethods()方法仅返回public方法,包括继承自父类的方法。

  7. 获取类的构造器: 通过getDeclaredConstructors()方法可以获取类的所有构造器,而getConstructors()方法仅返回public构造器。

  8. 获取类的注解: 如果类、方法、字段等上面有注解(Annotation),可以使用getAnnotations()getDeclaredAnnotation()等方法来获取这些注解信息。

  9. 获取类的内部类和接口: 通过getDeclaredClasses()方法可以获取当前类中声明的所有内部类和接口。

  10. 判断类的特性Class类提供了一系列的方法来判断类的特性,如isInterface()isEnum()isAnnotation()isAnonymousClass()isArray()isPrimitive()等。

获取类运行时结构的能力在Java中非常强大,它允许开发者在程序运行时动态地分析和操作类,这在很多场景下都很有用,比如框架设计、单元测试、序列化和反序列化、依赖注入等。然而,使用反射也需要谨慎,因为它可能会破坏封装性,降低性能,并且使代码更加复杂和难以维护。

测试

首先,我们需要定义一个 User 类,

class User{
  private String name;
  private int id;
  private int age;

  public User(String name, int id, int age) {
    this.name = name;
    this.id = id;
    this.age = age;
  }

  public User() {
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }

  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }

  @Override
  public String toString() {
    return "User{" +
      "name='" + name + '\'' +
      ", id=" + id +
      ", age=" + age +
      '}';
  }
}

在代码示例中,Test05 类有一个 main 方法,该方法执行了以下操作:

  1. 创建了一个 User 类的对象 user
  2. 通过调用 user.getClass() 获取了 User 类的 Class 对象,并将其存储在变量 c1 中。
  3. 打印了 c1 所代表的类的全名(包名 + 类名)和简单类名(仅类名)。
  4. 打印了一行分隔符 -------
  5. 获取了 c1 所代表的类声明的所有字段(不包括继承的字段),并遍历打印了每个字段的信息。

public class Test05 {
  public static void main(String[] args) throws ClassNotFoundException {
    User user = new User();
    Class c1 = user.getClass();
    System.out.println(c1.getName());
    System.out.println(c1.getSimpleName());

    System.out.println("-------");
    // Field[] fields = c1.getFields();
    Field[] fields = c1.getDeclaredFields();
    for(Field f: fields){
      System.out.println(f);
    }

  }
}

【注解和反射】获取类运行时结构,java,java,开发语言,intellij-idea,class

这里是输出结果的详细分析:

  1. System.out.println(c1.getName()); 打印了User类的完全限定名,即包括包名(如果有的话)和类名。因为User类没有指定包名,所以输出就是User

  2. System.out.println(c1.getSimpleName()); 打印了User类的简单名字,也就是不包括包名的类名,所以输出还是User

  3. 在打印了一行分隔符之后,代码通过c1.getDeclaredFields()获取了User类中声明的所有字段,包括privateprotected、默认(包私有)和public字段。在这个例子中,User类有三个private字段:nameidage。这些字段被打印出来,包括它们的访问修饰符、类型、类名和字段名。

getFields()和getDeclaredFields()

在Java的反射API中,getFields()getDeclaredFields()方法都用于获取类的字段,但它们在获取字段的范围和访问权限上有明显的区别:

  1. getFields():

    • 这个方法返回的是当前类及其所有父类(包括Object类)中声明的public字段
    • 它不包括当前类中声明的privateprotected和默认(包私有)访问级别的字段。
    • 如果当前类或其父类中没有public字段,那么这个方法将返回一个长度为0的数组。
  2. getDeclaredFields():

    • 这个方法返回的是当前类中声明的所有字段,无论它们的访问权限是什么(publicprivateprotected或默认)。
    • 它不包括父类中声明的任何字段,只查看当前类的字段。
    • 即使当前类中没有字段,这个方法也会返回一个数组,只不过数组的长度是0。

通常,如果你只对当前类的字段感兴趣,而不关心父类的字段,那么你应该使用getDeclaredFields()。同时,如果你需要访问非public字段,你也需要使用getDeclaredFields(),因为getFields()不会返回这些字段。

另外,值得注意的是,如果你使用getDeclaredFields()获取了非public字段,并且想要访问或修改这些字段的值,你需要先调用Field.setAccessible(true)来允许访问这些字段,否则会抛出IllegalAccessException异常。

getMethods()getDeclaredMethods()

现在,让我们来讨论getMethods()getDeclaredMethods()的区别:

  1. getMethods():

    • 这个方法返回当前类及其所有父类(包括Object类)中声明的所有public方法。
    • 它不包括当前类中声明的privateprotected和默认(包私有)访问级别的方法。
    • 返回的数组包含了从当前类开始,沿着继承链向上直到Object类的所有public方法。
  2. getDeclaredMethods():

    • 这个方法返回当前类中声明的所有方法,无论它们的访问权限是什么(publicprivateprotected或默认)。
    • 它不包括父类中声明的任何方法,只查看当前类的方法。
    • 即使当前类中没有方法,这个方法也会返回一个数组,只不过数组的长度是0。

与字段的情况类似,如果你只对当前类的方法感兴趣,而不关心父类的方法,那么你应该使用getDeclaredMethods()。同时,如果你需要访问非public方法,你也需要使用getDeclaredMethods(),因为getMethods()不会返回这些方法。

同样值得注意的是,如果你使用getDeclaredMethods()获取了非public方法,并且想要调用这些方法,你需要先调用Method.setAccessible(true)来允许访问这些方法,否则会抛出IllegalAccessException异常。文章来源地址https://www.toymoban.com/news/detail-861100.html

到了这里,关于【注解和反射】获取类运行时结构的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【JAVA】单元测试、反射、注解、动态代理

    @Test 测试方法 @Before 用来修饰实例方法,该方法会在每一个测试方法执行之前执行一次。 @After 用来修饰实例方法,该方法会在每一个测试方法执行之后执行一次。 @Before Class 用来静态修饰方法,该方法会在所有测试方法之前只执行一次。 @After Class 用来静态修饰方法,该方法

    2024年02月11日
    浏览(41)
  • Java补充内容(Junit 反射 注解)

    测试分类: 1. 黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值。 2. 白盒测试:需要写代码的。关注程序具体的执行流程。 Junit使用:白盒测试 步骤: 定义一个测试类(测试用例) 建议: 测试类名:被测试的类名Test CalculatorTest 包名:xxx.xxx.xx.test cn.itcast.

    2024年02月16日
    浏览(39)
  • Java高级技术:单元测试、反射、注解

    目录 单元测试 单元测试概述 单元测试快速入门 单元测试常用注解 反射 反射概述 反射获取类对象 反射获取构造器对象 反射获取成员变量对象 反射获取方法对象 反射的作用-绕过编译阶段为集合添加数据 反射的作用-通用框架的底层原理 注解 注解概述 自定义注解 元注解

    2024年01月16日
    浏览(49)
  • 反射 p4 反射获取类的结构信息

    关于Class的API getName:获取全类名 getSimpleName:获取简单类名 getFields:获取所有Public修饰的属性,包含本类及其父类(不仅仅是直接父类) getDeclaredFields:获取本类中的所有属性,不包括父类 getMethods:获取所有public修饰的方法,包含本类及其父类的(不仅仅是直接父类) ge

    2024年02月16日
    浏览(35)
  • JAVA使用反射机制和注解实现对信息的处理-----JAVA入门基础教程

    import java.lang.annotation.Annotation; import java.lang.reflect.Field; public class AnnotationTest { public static void main(String[] args) throws Exception { Class c = Class.forName(\\\"Customer\\\"); c = Customer.class; Table table = (Table)c.getDeclaredAnnotation(Table.class); System.out.println(table.value()); Annotation[] annotations = c.getDeclaredAnnotatio

    2024年02月15日
    浏览(44)
  • Day20-【Java SE高级】单元测试 反射 注解 动态代理

    就是针对最小的功能单元(方法),编写测试代码对其进行正确性测试。 1. 咱们之前是如何进行单元测试的?有啥问题? 只能在main方法编写测试代码,去调用其他方法进行测试。 无法实现自动化测试,一个方法测试失败,可能影响其他方法的测试。 无法得到测试的报告,需要程

    2024年04月17日
    浏览(50)
  • Java进阶(1)——JVM的内存分配 & 反射Class类的类对象 & 创建对象的几种方式 & 类加载(何时进入内存JVM)& 注解 & 反射+注解的案例

    1.java运行时的内存分配,创建对象时内存分配; 2.类加载的顺序,创建一个唯一的类的类对象; 3.创建对象的方式,new,Class.forName,clone; 4.什么时候加载.class文件进入JVM内存中,看到new,Class.forName; 5.如何加载?双亲委托(委派)机制:安全;AppClassLoader; 6.反射实质:能

    2024年02月14日
    浏览(41)
  • 【Java】后端开发语言Java和C#,两者对比注解和属性的区别以及作用

    欢迎来到《小5讲堂》 大家好,我是全栈小5。 这是《Java》序列文章,每篇文章将以博主理解的角度展开讲解, 特别是针对知识点的概念进行叙说,大部分文章将会对这些概念进行实际例子验证,以此达到加深对知识点的理解和掌握。 温馨提示:博主能力有限,理解水平有限

    2024年01月16日
    浏览(51)
  • golang反射获取结构体的值和修改值

    封装好就可以直接在service层使用了【自己手动复制粘贴】 或者嫌麻烦就放到【代码生成器】中,这样就不用每次都去写这个查询了

    2024年02月15日
    浏览(43)
  • Go语言通过反射获取各种类型变量的值

    反射是程序在运行期间获取变量的类型和值、或者执行变量的方法的能力。 反射是程序在运行期间获取变量的类型和值、或者执行变量的方法的能力。 Golang 反射包中有两对非常重要的函数和类型,两个函数分别是: reflect.TypeOf 能获取类型信息 reflect.Type; reflect.ValueOf 能获取

    2024年02月15日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包