• 5、java反射基础


    Class对象:

    Class对象记录了所有与类相关的信息,当类加载器从文件系统中加载.class文件到JVM中的同时会为每一个类创建一个Class对象。通过Class对象可以获取到类的属性、方法、构造器等全部与类相关的信息。

    现在假设在com.aop包下有一个抽象类和一个类,定义如下:

    package com.aop;
    
    abstract public class Creature<T> {
    
    }
     1 package com.aop;
     2 
     3 public class Person extends Creature<String>{
     4 
     5     int id;
     6     public String name;
     7     private int age;
     8     
     9     public Person() { }
    10     public Person(int age, String name){
    11         this.age = age;
    12         this.name = name;
    13     }
    14 
    15     public int getId() {
    16         return id;
    17     }
    18 
    19     public void setId(int id) {
    20         this.id = id;
    21     }
    22 
    23     public String getName() {
    24         return name;
    25     }
    26 
    27     public int getAge() {
    28         return age;
    29     }
    30 
    31     public void setName(String name) {
    32         this.name = name;
    33     }
    34 
    35     public void setAge(int age) {
    36         this.age = age;
    37     }
    38     
    39     static public void countAdd(int a, Integer b){
    40         System.out.println(a + " + " + b + " = " + (a+b));
    41     }
    42 
    43     public void show() {
    44         System.out.println("我是一个人!");
    45     }
    46 
    47     public void display(String nation) {
    48         System.out.println("我的国际是:" + nation);
    49     }
    50 
    51     @Override
    52     public String toString() {
    53         return "Person [name=" + name + ", age=" + age + "]";
    54     }
    55 
    56 }

    很简洁,定义一个带泛型的抽象类,Person继承自该抽象类。

    与反射相关的包:

    import java.lang.reflect.Constructor;  //与构造器相关
    import java.lang.reflect.Field;      //与域相关
    import java.lang.reflect.Method;      //与方法相关

    //还有其它的...

    1、Class对象的4中获取方式:

     1 package com.aop;
     2 
     3 import org.junit.Test;
     4 
     5 public class TestReflection {
     6     
     7     @Test
     8     public void testReflection() throws Exception{
     9         
    10         //1.调用运行时类本身的.class属性
    11         Class<Person> clazz1 = Person.class;
    12         
    13         //2.通过运行时类的对象获取
    14         Person person = new Person();
    15         Class<? extends Person> clazz2 = person.getClass();
    16         
    17         //3.通过Class的静态方法获取.通过此方式,体会一下,反射的动态性。
    18         String className = "com.aop.Person";
    19         
    20         Class<?> clazz3 = Class.forName(className);
    21         
    22         //4.(了解)通过类的加载器
    23         ClassLoader loader = this.getClass().getClassLoader();
    24         Class<?> clazz4 = loader.loadClass(className);
    25         
    26         System.out.println(clazz1.getName());
    27         System.out.println(clazz2.getName());
    28         System.out.println(clazz3.getName());
    29         System.out.println(clazz4.getName());
    30         
    31         System.out.println(clazz1 == clazz2);
    32         System.out.println(clazz1 == clazz3);
    33         System.out.println(clazz1 == clazz4);
    34     }
    35 }

    2、通过反射读取对象的属性值,并修改它们(能够读取与修改包括private权限的属性值

     1 @Test
     2     public void testField() throws Exception{
     3         String className = "com.aop.Person";
     4         Class<?> clazz = Class.forName(className);
     5         
     6         Person person = (Person) clazz.newInstance();
     7         
     8         //getField(...)方法会获取public类型的属性,包括父类的public类型属性都能获取
     9         Field field = clazz.getField("name");
    10         field.set(person, "东东");
    11         System.out.println(person);
    12         
    13         //getDeclaredField(...)获取所有所有类型的属性,但是,不包括父类的属性在内
    14         Field field2 = clazz.getDeclaredField("age");
    15         //如果类中的属性设定为private或者是“默认类型”,则需要设置其可访问属性
    16         field2.setAccessible(true);    
    17         field2.set(person, 100);
    18         System.out.println(person);
    19         
    20     }

    3、通过反射调用对象的方法

     1 @Test
     2     public void testMethod() throws Exception{
     3         String className = "com.aop.Person";
     4         Class<?> clazz = Class.forName(className);
     5         
     6         Person person = new Person(50, "哈哈");
     7         
     8         //获取并调用无参的show方法
     9         Method method1 = clazz.getMethod("show");
    10         method1.invoke(person);
    11         
    12         //获取并调用有参的display方法
    13         Method method2 = clazz.getMethod("display", String.class);
    14         method2.invoke(person, "中国");
    15         
    16         //调用有返回值的方法
    17         Method method3 = clazz.getMethod("toString");
    18         Object resultVal = method3.invoke(person);
    19         System.out.println(resultVal);
    20         
    21         //调用有参数的静态方法
    22         Method method4 = clazz.getMethod("countAdd", int.class, Integer.class);
    23         method4.invoke(Person.class, 10, 100);
    24     }

    4、通过反射调用带参构造器来实例化一个对象

     1     @Test
     2     public void testConstructor() throws Exception{
     3         String className = "com.aop.Person";
     4         Class<?> clazz = Class.forName(className);
     5         
     6         //调用一个有参的构造器
     7         Constructor<?> cons = clazz.getConstructor(int.class, String.class);
     8         Person person = (Person) cons.newInstance(20, "兮兮");
     9         System.out.println(person);
    10     }

    5、获取“父类”、“带泛型的父类”、“父类的泛型

     1 @Test
     2     public void testGeneric() throws Exception{
     3         String className = "com.aop.Person";
     4         Class<?> clazz = Class.forName(className);
     5         
     6         //1、获取父类,只能得到父类的名称
     7         Class<?> superClazz = clazz.getSuperclass();
     8         System.out.println(superClazz);
     9         
    10         //2、获取带泛型的父类
    11         Type type = clazz.getGenericSuperclass();
    12         System.out.println(type);
    13         
    14         //3、获取父类的泛型类(重要)
    15         ParameterizedType param = (ParameterizedType)type;
    16         Type[] argmts = param.getActualTypeArguments();
    17         Class<?> claz = (Class<?>)argmts[0];
    18         System.out.println(claz);
    19     }

    下面是全部的源代码:

    1 package com.aop;
    2 
    3 abstract public class Creature<T> {
    4 
    5 }
    abstract public class Creature
     1 package com.aop;
     2 
     3 public class Person extends Creature<String>{
     4 
     5     int id;
     6     public String name;
     7     private int age;
     8     
     9     public Person() { }
    10     public Person(int age, String name){
    11         this.age = age;
    12         this.name = name;
    13     }
    14 
    15     public int getId() {
    16         return id;
    17     }
    18 
    19     public void setId(int id) {
    20         this.id = id;
    21     }
    22 
    23     public String getName() {
    24         return name;
    25     }
    26 
    27     public int getAge() {
    28         return age;
    29     }
    30 
    31     public void setName(String name) {
    32         this.name = name;
    33     }
    34 
    35     public void setAge(int age) {
    36         this.age = age;
    37     }
    38     
    39     static public void countAdd(int a, Integer b){
    40         System.out.println(a + " + " + b + " = " + (a+b));
    41     }
    42 
    43     public void show() {
    44         System.out.println("我是一个人!");
    45     }
    46 
    47     public void display(String nation) {
    48         System.out.println("我的国际是:" + nation);
    49     }
    50 
    51     @Override
    52     public String toString() {
    53         return "Person [name=" + name + ", age=" + age + "]";
    54     }
    55 
    56 }
    public class Person extends Creature
      1 package com.aop;
      2 
      3 import java.lang.reflect.Constructor;
      4 import java.lang.reflect.Field;
      5 import java.lang.reflect.Method;
      6 import java.lang.reflect.ParameterizedType;
      7 import java.lang.reflect.Type;
      8 
      9 import org.junit.Test;
     10 
     11 public class TestReflection {
     12     
     13     @Test
     14     public void testReflection() throws Exception{
     15         
     16         //1.调用运行时类本身的.class属性
     17         Class<Person> clazz1 = Person.class;
     18         
     19         //2.通过运行时类的对象获取
     20         Person person = new Person();
     21         Class<? extends Person> clazz2 = person.getClass();
     22         
     23         //3.通过Class的静态方法获取.通过此方式,体会一下,反射的动态性。
     24         String className = "com.aop.Person";
     25         
     26         Class<?> clazz3 = Class.forName(className);
     27         
     28         //4.(了解)通过类的加载器
     29         ClassLoader loader = this.getClass().getClassLoader();
     30         Class<?> clazz4 = loader.loadClass(className);
     31         
     32         System.out.println(clazz1.getName());
     33         System.out.println(clazz2.getName());
     34         System.out.println(clazz3.getName());
     35         System.out.println(clazz4.getName());
     36         
     37         System.out.println(clazz1 == clazz2);
     38         System.out.println(clazz1 == clazz3);
     39         System.out.println(clazz1 == clazz4);
     40     }
     41     
     42     @Test
     43     public void testField() throws Exception{
     44         String className = "com.aop.Person";
     45         Class<?> clazz = Class.forName(className);
     46         
     47         Person person = (Person) clazz.newInstance();
     48         
     49         //getField(...)方法会获取public类型的属性,包括父类的public类型属性都能获取
     50         Field field = clazz.getField("name");
     51         field.set(person, "东东");
     52         System.out.println(person);
     53         
     54         //getDeclaredField(...)获取所有所有类型的属性,但是,不包括父类的属性在内
     55         Field field2 = clazz.getDeclaredField("age");
     56         //如果类中的属性设定为private或者是“默认类型”,则需要设置其可访问属性
     57         field2.setAccessible(true);    
     58         field2.set(person, 100);
     59         System.out.println(person);
     60         
     61     }
     62     
     63     @Test
     64     public void testMethod() throws Exception{
     65         String className = "com.aop.Person";
     66         Class<?> clazz = Class.forName(className);
     67         
     68         Person person = new Person(50, "哈哈");
     69         
     70         //获取并调用无参的show方法
     71         Method method1 = clazz.getMethod("show");
     72         method1.invoke(person);
     73         
     74         //获取并调用有参的display方法
     75         Method method2 = clazz.getMethod("display", String.class);
     76         method2.invoke(person, "中国");
     77         
     78         //调用有返回值的方法
     79         Method method3 = clazz.getMethod("toString");
     80         Object resultVal = method3.invoke(person);
     81         System.out.println(resultVal);
     82         
     83         //调用有参数的静态方法
     84         Method method4 = clazz.getMethod("countAdd", int.class, Integer.class);
     85         method4.invoke(Person.class, 10, 100);
     86     }
     87     
     88     @Test
     89     public void testConstructor() throws Exception{
     90         String className = "com.aop.Person";
     91         Class<?> clazz = Class.forName(className);
     92         
     93         //调用一个有参的构造器
     94         Constructor<?> cons = clazz.getConstructor(int.class, String.class);
     95         Person person = (Person) cons.newInstance(20, "兮兮");
     96         System.out.println(person);
     97     }
     98     
     99     @Test
    100     public void testGeneric() throws Exception{
    101         String className = "com.aop.Person";
    102         Class<?> clazz = Class.forName(className);
    103         
    104         //1、获取父类,只能得到父类的名称
    105         Class<?> superClazz = clazz.getSuperclass();
    106         System.out.println(superClazz);
    107         
    108         //2、获取带泛型的父类
    109         Type type = clazz.getGenericSuperclass();
    110         System.out.println(type);
    111         
    112         //3、获取父类的泛型类(重要)
    113         ParameterizedType param = (ParameterizedType)type;
    114         Type[] argmts = param.getActualTypeArguments();
    115         Class<?> claz = (Class<?>)argmts[0];
    116         System.out.println(claz);
    117     }
    118 
    119 }
    public class TestReflection

    参考:尚硅谷java视频

  • 相关阅读:
    数字签名与HTTPS详解
    利用策略模式优化过多 if else 代码
    Redis 的事务到底是不是原子性的
    Spring Boot项目的接口防刷
    深入分析 ThreadLocal
    什么是四层和七层负载均衡?他们之间的区别是什么?
    MyEclipse或Eclipse中project的导入和导出
    org.hibernate.exception.ConstraintViolationException: could not insert:
    C++ STL vector(向量容器)的使用(附完整程序代码)
    Swift2.0语言教程之函数嵌套调用形式
  • 原文地址:https://www.cnblogs.com/lj95801/p/5392628.html
Copyright © 2020-2023  润新知