• 【注释和反射】获取class类实例的方法


    目录

    一、获取一个类的Class对象的几种方法

    代码

    二、哪些类型可以有Class对象?

    代码


    一、获取一个类的Class对象的几种方法

    Class对象是访问类元数据的入口,通过它可以获取类的名称、方法、字段、构造器、注解等信息,还可以创建类的实例、调用方法等。

    在Java中,获取一个类的Class对象主要有以下几种方式:

    (1)使用.class语法: 对于任何类型(包括基本类型)的变量,都可以使用.class来获取其Class对象。

    (2)使用对象的getClass()方法: 如果你有一个对象,你可以调用它的getClass()方法来获取它的Class对象。

    (3)使用Class.forName()方法: 如果你知道类的全名(包括包名),你可以使用Class.forName()方法来获取其Class对象。这种方式通常用于动态加载类。

    (4)使用对象的getSuperclass()方法:一个已经存在的Class对象,代表某个类的类型。调用getSuperclass()方法会返回表示该类父类的Class对象。如果该类没有显式地继承其他类,那么它隐式地继承自java.lang.Object类,因此getSuperclass()方法将返回Object类的Class对象。

    (5)使用基本类型的包装类中的TYPE字段: 对于基本类型,它们的包装类都有一个名为TYPE的静态字段,该字段是该基本类型的Class对象。

    注意:int.classInteger.class是不同的,前者是基本类型的Class对象,后者是包装类的Class对象。

    代码

    在这个代码中,展示了获取一个类的Class对象的几种方法,并调用了c4.hashCode()方法,这会返回c4对象(即表示父类的Class对象)的哈希码。哈希码通常用于在哈希表等数据结构中快速定位对象。

    每个对象的哈希码在对象的生命周期内应该保持一致,并且不同的对象根据equals()方法的比较结果,可能拥有相同的哈希码(这种情况称为哈希冲突)。 

    1. public class Test {
    2. public static void main(String[] args) throws ClassNotFoundException {
    3. Person person = new Student();
    4. System.out.println(person.name);
    5. Class c1 = person.getClass();
    6. System.out.println(c1.hashCode());
    7. Class c2 = Student.class;
    8. System.out.println(c2.hashCode());
    9. Class c3 = Class.forName("com.itheima.sjms.Student");
    10. System.out.println(c3.hashCode());
    11. Class c4 = c1.getSuperclass();
    12. System.out.println(c4.hashCode());
    13. Class c5 = Person.class;
    14. System.out.println(c5.hashCode());
    15. Class c6 = Integer.TYPE;
    16. System.out.println(c6.hashCode());
    17. }
    18. }
    19. class Person{
    20. String name;
    21. public Person(String name){
    22. this.name = name;
    23. }
    24. public Person() {
    25. }
    26. @Override
    27. public String toString() {
    28. return "Person{" +
    29. "name='" + name + '\'' +
    30. '}';
    31. }
    32. }
    33. class Student extends Person{
    34. public Student() {
    35. this.name = "学生";
    36. }
    37. }
    38. class Teacher extends Person{
    39. public Teacher() {
    40. this.name = "老师";
    41. }
    42. }

    总结:在Java中,获取Class对象的方式主要有.class语法、对象的getClass()方法、Class.forName()方法以及基本类型的包装类中的TYPE字段(但通常我们使用.class语法来获取基本类型的Class对象)。

    • 若已知具体的类,通过类的class属性获取,该方法最为安全可靠,程序性能最高
    • 已知某个类的实例,调用该实例的getClass()方法获取Class对象
    • 已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取,可能抛出ClassNotFoundException
    • 内置基本数据类型可以直接用类名.Type
    • 还可以利用ClassLoader

    二、哪些类型可以有Class对象?

    Class对象是访问类元数据的入口,通过它可以获取类的名称、方法、字段、构造器、注解等信息,还可以创建类的实例、调用方法等。

    在Java中,几乎所有类型都可以有对应的Class对象。这些类型包括:

    代码

    在这个代码中,展示了可以有Class对象的一些类型,

    1. 普通类(包括内部类和匿名类): 每个加载到JVM中的普通类都会有一个对应的Class对象。这包括顶层类、嵌套类(静态内部类)和非静态内部类。

    2. 接口: 接口也有对应的Class对象。虽然接口不能实例化,但它们的Class对象描述了接口的结构,包括方法签名等。

    3. 数组: 数组在Java中是对象,并且每种数组类型都有其对应的Class对象。例如,int[].classString[].class分别表示整型数组和字符串数组的Class对象。

    4. 基本类型: 虽然基本类型(如intcharboolean等)不是对象,但Java为每种基本类型提供了包装类(如IntegerCharacterBoolean等),并且每种基本类型都有其对应的Class对象,如int.class。不过要注意,这里的int.class实际上是一个特殊语法,因为基本类型本身不是类。这种语法是为了在反射时能够方便地获取基本类型的Class对象。

    5. 枚举: 枚举类型在Java中是特殊的类,每个枚举类型都有一个Class对象。

    6. 注解类型: 注解也是一种特殊的接口,它们也有自己的Class对象。

    7. oid类型void类型也有对应的Class对象,即void.class。虽然void类型表示无返回值,但在反射中有时需要表示方法的返回类型为void

    8. 泛型类型: 泛型类型本身在运行时由于类型擦除不会有特定的Class对象。但是,你可以获取表示泛型边界或泛型超类的Class对象。例如,List.class这样的表达式是不合法的,但你可以获取List.class并通过反射来检查其泛型信息(尽管这些信息在运行时是受限的)。

    1. import scala.Int;
    2. import java.lang.annotation.ElementType;
    3. public class Test {
    4. public static void main(String[] args){
    5. test2();
    6. }
    7. public static void test2(){
    8. Class c1 = Object.class; // 类
    9. Class c2 = int[].class; // 一维数组
    10. Class c3 = String[][].class; // 二维数组
    11. Class c4 = void.class; // void
    12. Class c5 = Override.class; // 注解
    13. Class c6 = Integer.class; // 基本数据类型
    14. Class c7 = Class.class; // Class
    15. Class c8 = ElementType.class; // 枚举
    16. Class c9 = Comparable.class; // 接口
    17. System.out.println(c1);
    18. System.out.println(c2);
    19. System.out.println(c3);
    20. System.out.println(c4);
    21. System.out.println(c5);
    22. System.out.println(c6);
    23. System.out.println(c7);
    24. System.out.println(c8);
    25. System.out.println(c9);
    26. }
    27. public static void test1() throws ClassNotFoundException {
    28. Person person = new Student();
    29. System.out.println(person.name);
    30. Class c1 = person.getClass();
    31. System.out.println(c1.hashCode());
    32. Class c2 = Student.class;
    33. System.out.println(c2.hashCode());
    34. Class c3 = Class.forName("com.itheima.sjms.Student");
    35. System.out.println(c3.hashCode());
    36. Class c4 = c1.getSuperclass();
    37. System.out.println(c4.hashCode());
    38. Class c5 = Person.class;
    39. System.out.println(c5.hashCode());
    40. Class c6 = Integer.TYPE;
    41. System.out.println(c6.hashCode());
    42. }
    43. }
    44. class Person{
    45. String name;
    46. public Person(String name){
    47. this.name = name;
    48. }
    49. public Person() {
    50. }
    51. @Override
    52. public String toString() {
    53. return "Person{" +
    54. "name='" + name + '\'' +
    55. '}';
    56. }
    57. }
    58. class Student extends Person{
    59. public Student() {
    60. this.name = "学生";
    61. }
    62. }
    63. class Teacher extends Person{
    64. public Teacher() {
    65. this.name = "老师";
    66. }
    67. }

    同时,我们也可以看到,两个长度不一样的数组,只要它们类型一(,此处都是int类型),那么它们的哈希code,也就是它们底层的Class类依旧是一样的,和数组的长度无关。

    1. int[] arr1 = new int[10];
    2. int[] arr2 = new int[100];
    3. System.out.println(arr1.getClass().hashCode());
    4. System.out.println(arr2.getClass().hashCode());

  • 相关阅读:
    JAVA基础--MAVEN
    句子嵌入: 交叉编码和重排序
    $value$plusargs字符串参数传递后如何随机
    双十一不踩雷的好物怎么选,几款最值得入手的好物推荐
    【python】使用docx获取word文档的标题等级、大纲等级和编号等级
    使用QT实现http里面的get和post
    Leetcode682:棒球比赛
    计算机网络数据链路层知识总结
    leetcode(力扣) 59. 螺旋矩阵 II (边界控制思路)
    java教室预约管理系统
  • 原文地址:https://blog.csdn.net/qq_45956730/article/details/138169085