JavaSE:反射机制 - Class类

1.  基本概念

    <1>  java.lang.Class类的实例,可以用于描述Java应用程序中的类和接口,也就是一种数据类型

    <2>  该类没有公共构造方法,该类的实例由Java虚拟机和类加载器自动构造完成,本质上就是加载到内存中的运行时

 

2.  获取Class对象的方式

    <1>  数据类型.class:获取对应类型的Class对象(掌握)

    <2>  引用/对象.getClass():获取对应类型的Class对象

    <3>  包装类.TYPE:获取对应基本数据类型的Class对象

    <4>  Class.forName():获取参数指定类型的Class对象(掌握)

    <5>  类加载器ClassLoader:获取指定类型的Class对象

 

3.  代码示例 - ClassTest.java

 

public class ClassTest {

    public static void main(String[] args) throws ClassNotFoundException {

        // 1.使用数据类型.class的方式可以获取对应类型的Class对象
        Class c1 = String.class;
        System.out.println("c1 = " + c1); // 自动调用toString方法  class java.lang.String
        c1 = int.class;
        System.out.println("c1 = " + c1); // int
        c1 = void.class;
        System.out.println("c1 = " + c1); // void

        System.out.println("---------------------------------------------------");
        // 2.使用对象.getClass()的方式获取对应的Class对象
        String str1 = new String("hello");
        c1 = str1.getClass();
        System.out.println("c1 = " + c1); // class java.lang.String

        Integer it1 = 20;
        c1 = it1.getClass();
        System.out.println("c1 = " + c1); // class java.lang.Integer

        int num = 5;
        //num.getClass(); Error: 基本数据类型的变量不能调用方法

        System.out.println("---------------------------------------------------");
        // 3.使用包装类.TYPE的方式来获取对应基本数据类型的Class对象
        c1 = Integer.TYPE;
        System.out.println("c1 = " + c1); // int

        c1 = Integer.class;
        System.out.println("c1 = " + c1); // class java.lang.Integer

        System.out.println("---------------------------------------------------");
        // 4.调用Class类中的forName方法来获取对应的Class对象
        //c1 = Class.forName("String"); // Error  要求写完整的名称:包名.类名
        c1 = Class.forName("java.lang.String");
        System.out.println("c1 = " + c1); // class java.lang.String

        c1 = Class.forName("java.util.Date");
        System.out.println("c1 = " + c1); // class java.util.Date

        //c1 = Class.forName("int");
        //System.out.println("c1 = " + c1); // 不能获取基本数据类型的Class对象

        System.out.println("---------------------------------------------------");
        // 5.使用类加载器的方式来获取Class对象
        ClassLoader classLoader = ClassTest.class.getClassLoader();
        System.out.println("classLoader = " + classLoader); // null
        c1 = classLoader.loadClass("java.lang.String");
        System.out.println("c1 = " + c1); // class java.lang.String
    }
}

 

4.  Class类的常用方法(掌握)

static Class<?> forName(String className) 用于获取参数指定类型对应的Class对象,并返回
T newInstance() 用于创建该Class对象所表示类的新实例

 

5.  newInstance的代码示例 - PersonConstructorTest.java & Person.java 

 1 public class PersonConstructorTest {
 2 
 3     public static void main(String[] args) throws Exception {
 4 
 5         // 1.使用原始方式以无参形式构造Person类型的对象并打印
 6         Person p1 = new Person();
 7         System.out.println("无参方式创建的对象是:" + p1); // null 0
 8 
 9         System.out.println("---------------------------------------------------");
10         // 2.使用反射机制以无参形式构造Person类型的对象并打印
11         // 创建对象的类型可以从键盘输入
12         //System.out.println("请输入要创建对象的类型:");
13         //Scanner sc = new Scanner(System.in);
14         //String str1 = sc.next();
15         //Class c1 = Class.forName("com.lagou.task20.Person");
16         // 创建对象的类型可以从配置文件中读取
17         BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("d:/a.txt")));
18         String str1 = br.readLine();
19         Class c1 = Class.forName(str1);
20         //System.out.println("无参方式创建的对象是:" + c1.newInstance()); // null 0
21         // 获取Class对象对应类中的无参构造方法,也就是Person类中的无参构造方法
22         Constructor constructor = c1.getConstructor();
23         // 使用获取到的无参构造方法来构造对应类型的对象,也就是Person类型的对象
24         System.out.println("无参方式创建的对象是:" + constructor.newInstance());
25         //sc.close();
26         br.close();
27 
28         System.out.println("---------------------------------------------------");
29         // 3.使用原始方式以有参方式构造Person类型的对象并打印
30         Person p2 = new Person("zhangfei", 30);
31         System.out.println("有参方式构造的对象是:" + p2); // zhangfei 30
32 
33         System.out.println("---------------------------------------------------");
34         // 4.使用反射机制以有参方式构造Person类型的对象并打印
35         // 获取Class对象对应类中的有参构造方法,也就是Person类中的有参构造方法
36         Constructor constructor1 = c1.getConstructor(String.class, int.class);
37         // 使用获取到的有参构造方法来构造对应类型的对象,也就是Person类型的对象
38         // newInstance方法中的实参是用于给有参构造方法的形参进行初始化的,也就是给name和age进行初始化的
39         System.out.println("有参方式构造的对象是:" + constructor1.newInstance("zhangfei", 30)); // zhangfei 30
40 
41         System.out.println("---------------------------------------------------");
42         // 5.使用反射机制获取Person类中所有的公共构造方法并打印
43         Constructor[] constructors = c1.getConstructors();
44         for (Constructor ct : constructors) {
45             System.out.println("构造方法的访问修饰符是:" + ct.getModifiers());
46             System.out.println("构造方法的方法名称是:" + ct.getName());
47             Class[] parameterTypes = ct.getParameterTypes();
48             System.out.print("构造方法的所有参数类型是:");
49             for (Class cs : parameterTypes) {
50                 System.out.print(cs + " ");
51             }
52             System.out.println();
53             System.out.println("-------------------------------------------------");
54         }
55     }
56 }

 

 1 public class Person {
 2     private String name;
 3     //public String name;
 4     private int age;
 5 
 6     public Person() {
 7     }
 8 
 9     public Person(String name, int age) {
10         this.name = name;
11         this.age = age;
12     }
13 
14     public String getName() {
15         return name;
16     }
17 
18     public void setName(String name) {
19         this.name = name;
20     }
21 
22     public int getAge() {
23         return age;
24     }
25 
26     public void setAge(int age) throws IOException {
27         this.age = age;
28     }
29 
30     @Override
31     public String toString() {
32         return "Person{" +
33                 "name='" + name + '\'' +
34                 ", age=" + age +
35                 '}';
36     }
37 }

<1> 直接创建对象

 

 <2>通过读取键盘输入的方式,创建对象

 

 

 

 <3>  通过读取配置文件的方式,创建对象

 

 

 

 <4>  由上可知,newInstance()已经过时了,可以使用Constructor类中的方法替代 (见下一篇文章)

 

posted @ 2021-06-16 09:20  Jasper2003  阅读(56)  评论(0编辑  收藏  举报