• Class类


    Class类

             在 Object类中定义了以下的方法,此方法将被所有子类继承 

    public final Class getClass();

            以上的方法返回值的类型是一个Class类,此类是Java反射的源头,实际上所谓反射从程序的运行结果来看也很好理解,即:可以通过对象反射出类的名称。

            对象照镜子后可以得到的信息:某个类的属性、方法和构造器、某个类到底实现类哪些接口。对于每个类而言,JRE都为其保留一个不变的 Class 类型的对象。一个 Class 对象包含了特定某个结构(class / interface / enum / annotation / primitive type / void / [])的有关信息。

    • Class 本身也是一个类
    • Class 对象只能由系统建立对象
    • 一个加载的类在 JVM 中只会有一个 Class 实例
    • 一个 Class 对象对应的是一个加载到 JVM 中的一个 .class 文件
    • 每个类的实例都会记得自己是由哪个 Class 实例所生成
    • 通过 Class 可以完整地得到一个类中的所有被加载的结构
    • Class 类是Reflection 的根源,针对任何你想动态加载、运行的类,唯有先获得相应的Class对象

    获取Class类的实例

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

    例子:

    1. package com.reflection;
    2. //测试class类的创建方式有哪些
    3. public class Test03 {
    4. public static void main(String[] args) throws ClassNotFoundException {
    5. Person person = new Student();
    6. System.out.println("这个人是:" + person.name);
    7. //方法一:通过对象获得
    8. Class c1 = person.getClass();
    9. System.out.println(c1.hashCode());
    10. //方法二:forname获得
    11. Class c2 = Class.forName("com.reflection.Student");
    12. System.out.println(c2.hashCode());
    13. //方法三:通过类名.class获得
    14. Class c3 = Student.class;
    15. System.out.println(c3.hashCode());
    16. //方法四:基本内置类型的包装类都有一个Type属性
    17. Class c4 = Integer.TYPE;
    18. System.out.println(c4);
    19. //获得父类类型
    20. Class c5 = c1.getSuperclass();
    21. System.out.println(c5);
    22. }
    23. }
    24. class Person {
    25. public String name;
    26. //构造器
    27. public Person() {
    28. }
    29. public Person(String name) {
    30. this.name = name;
    31. }
    32. @Override
    33. public String toString() {
    34. return "Person{" +
    35. "name='" + name + '\'' +
    36. '}';
    37. }
    38. }
    39. class Student extends Person {
    40. public Student() {
    41. this.name = "学生";
    42. }
    43. }
    44. class Teacher extends Person {
    45. public Teacher() {
    46. this.name = "老师";
    47. }
    48. }

    输出结果:

     哪些类型可以有Class对象

    • class:外部类,成员(成员内部类,静态内部类),局部内部类,匿名内部类
    • interface:接口
    • [ ]:数组    (只要元素类型与维度一样,就是同一个Class类)
    • enum:枚举
    • annotation:注解 @interface
    • primitive type:基本数据类型
    • void

    例子:

    1. package com.reflection;
    2. import java.lang.annotation.ElementType;
    3. public class Test04 {
    4. public static void main(String[] args) {
    5. Class c1 = Object.class;
    6. Class c2 = Comparable.class;//接口
    7. Class c3 = String[].class;//一维数组
    8. Class c4 = int[][].class;//二维数组
    9. Class c5 = Override.class;//注解类型
    10. Class c6 = ElementType.class;//枚举类型
    11. Class c7 = Integer.class;//基本数据类型
    12. Class c8 = void.class;//void类型
    13. Class c9 = Class.class;//class类型
    14. System.out.println(c1);
    15. System.out.println(c2);
    16. System.out.println(c3);
    17. System.out.println(c4);
    18. System.out.println(c5);
    19. System.out.println(c6);
    20. System.out.println(c7);
    21. System.out.println(c8);
    22. System.out.println(c9);
    23. //数组类型一样,长度不一样,最后输出的hashCode是一样的
    24. //只要元素类型与维度一样,就是同一个Class.
    25. int[] a = new int[10];
    26. int[] b = new int[100];
    27. System.out.println(a.getClass().hashCode());
    28. System.out.println(b.getClass().hashCode());
    29. }
    30. }

    输出结果:

    Class类的常用方法 

    方法名功能说明
    static ClassforName(String name)返回指定类名 name 的 Calss 对象
    Object newInstance()调用缺省构造函数,返回Class对象的一个实例
    getName()返回此 Class 对象所表示的实体(类,接口,数组类或 void)的名称
    Class getSuperClass()返回当前 Class 对象的父类的 Class 对象 
    Class[] getinterfaces()获取当前 Class对象的接口
    ClassLoader getClassLoader()返回该类的类加载器
    Constructor[] getConstructors()返回一个包含某些 Constructor 对象的数组
    Method getMothed(String name , Class...)返回一个 Method 对象,此对象的形参类型为 param Type
    Field[] getDeclaredFields()返回 Field 对象的一个数组

    扩展:

    枚举:

            枚举常量是一种枚举类型中的值,及枚举值,枚举类型是由用户自定义的,只用用户在程序中定义它才能被使用。

    创建一个枚举类型的基本语法:
    enum 枚举类型名{
           枚举值1,枚举值2,…
    }
    枚举类型名是由用户自定义的,同时枚举值通常都会用大写,多个枚举值之间用逗号隔开。

    枚举优点:

    1. 代码的可读性提高了
    2. 有效减少参数传递的错误率
    3. 使用枚举来写switch语句会变得更加简洁以及清晰
    4. 枚举的代码看起来很简洁

    枚举常用方法:

    (1)values():把我们的枚举类型转换成数组

    1. public static void main(String[] args) {
    2. //将枚举类型转换成数组
    3. season[] arr1 = season.values();
    4. //利用for each循环进行打印
    5. for(season item : arr1)
    6. {
    7. System.out.println(item);
    8. }
    9. }
    10. public enum season{
    11. SPRING , SUMMER , AUTUMN , WINTER
    12. }

    输出结果:

    (2)ordinal():获得当前枚举类型的下标

    1. public static void main(String[] args) {
    2. //先将枚举类型转换成数组
    3. week[] arr = week.values();
    4. //循环遍历
    5. for(week item : arr)
    6. {
    7. //返回下标
    8. int index = item.ordinal();
    9. System.out.println(index);
    10. }
    11. }
    12. public enum week{
    13. MONDAY , TUESDAY , WEDNESDAY , THURSDAY , FRIDAY , SATURDAY , SUNDAY
    14. }

    输出结果:

    (3)valueOf():将一个字符串变成我们的枚举类型,若我们原本的枚举类型里不包含该字符串转换后的枚举值,那么系统会报错提示

    1. public static void main(String[] args) {
    2. //自定义字符串
    3. String str1 = "RED";
    4. //转换成已有的枚举类型
    5. Color color1 = Color.valueOf(str1);
    6. System.out.println(color1);
    7. //我们的枚举类里没有BLACK
    8. String str2 = "BLACK";
    9. //所以在这里的转换会产生错误
    10. Color color2 = Color.valueOf(str2);
    11. System.out.println(color2);
    12. }
    13. public enum Color{
    14. RED , GREEN , BLUE
    15. }

    运行结果:

    ​ 

    (4)compareTo():利用枚举的下标进行比较,得到下标相减得值

    1. public static void main(String[] args) {
    2. Color color1 = Color.RED;
    3. Color color2 = Color.GREEN;
    4. Color color3 = Color.BLUE;
    5. //比较RED和GREEN(0-1)
    6. int ret1 = color1.compareTo(color2);
    7. System.out.println(ret1);
    8. //比较RED和BLUE(0-2)
    9. int ret2 = color1.compareTo(color3);
    10. System.out.println(ret2);
    11. //比较GREEN和BLUE(1-2)
    12. int ret3 = color2.compareTo(color3);
    13. System.out.println(ret3);
    14. //比较BLUE和RED(2-0)
    15. int ret4 = color3.compareTo(color1);
    16. System.out.println(ret4);
    17. }
    18. public enum Color{
    19. RED , GREEN , BLUE
    20. }

    运行结果:

  • 相关阅读:
    哪种网站适合物理服务器
    好强型性格分析,如何改变好强型性格?
    助力商家高效接单发货,震坤行物流服务再升级
    QT应用启动失败排查方法
    美国侦查卫星-KeyHole锁眼卫星0.6m-1.2m
    LiveMeida视频接入网关
    NOSQL之Redis配置与优化
    [C++]多态是如何调用不同的函数对象的?
    自动控制原理9.4---李雅普诺夫稳定性分析
    JVS低代码如何实现复杂物料编码?
  • 原文地址:https://blog.csdn.net/qq_46423017/article/details/126016224