• Java 基础-反射


    反射-Reflect

    测试用到的代码

    1.接口 Person.java

    1 public interface Person {
    2     Boolean isMale = true;
    3 
    4     void say();
    5 
    6     void eat();
    7 
    8     void sleep();
    9 }

    2. Man.java 

     1 public class Man implements Person {
     2     private String name;
     3     private int age;
     4 
     5     public Man() {
     6     }
     7 
     8     public Man(String name) {
     9         this.name = name;
    10     }
    11 
    12     public Man(int age) {
    13         this.age = age;
    14     }
    15 
    16     public Man(String name, int age) {
    17         this.name = name;
    18         this.age = age;
    19     }
    20 
    21     private String test1(String name, int age) {
    22         return name + String.valueOf(age);
    23     }
    24 
    25     @Override
    26     public void say() {
    27         System.out.println("I am Man");
    28     }
    29 
    30     public void sayName(String name) {
    31         System.out.println("I am " + name);
    32     }
    33 
    34     public static void sayStatic() {
    35         System.out.println("This is a static method");
    36     }
    37 
    38     public static void sayStatic2(String name) {
    39         System.out.println("This is a static method,I am " + name);
    40     }
    41 
    42     @Override
    43     public void eat() {
    44         System.out.println("Man eat 5 breads");
    45     }
    46 
    47     @Override
    48     public void sleep() {
    49         System.out.println("Man need sleep 8 hours");
    50     }
    51 
    52     @Override
    53     public String toString() {
    54         return this.name + ":" + this.age;
    55     }
    56 }

     

    3. Women.java

     1 public class Women implements Person {
     2     @Override
     3     public void say() {
     4         System.out.println("I am women");
     5     }
     6 
     7     @Override
     8     public void eat() {
     9         System.out.println("Women eat 3 breads");
    10     }
    11 
    12     @Override
    13     public void sleep() {
    14         System.out.println("Women sleep 8 hours");
    15     }
    16 }

     

    4. Child.java

    1 public class Child extends Man {
    2 
    3     @Override
    4     public void say() {
    5         System.out.println("I am Child");
    6     }
    7 }

    通过反射,获取到类的信息和操作

    1.获取到类完整的包名和类名

    1 public class ReflectTest {
    2     public static void main(String[] args) {
    3         Class<?> c = Man.class;
    4         String name = c.getName();
    5         System.out.println(name);
    6     }
    7 }

    结果:

    cc.lijingbo.script.reflect.Man

    2.实例化 Class 类对象,有三种方法可以获取到 Class 对象。

     1 public class ReflectTest {
     2     public static void main(String[] args) {
     3         Class<?> c1 = null;
     4         Class<?> c2 = null;
     5         Class<?> c3 = null;
     6 
     7         c1 = Man.class;
     8         Man man = new Man();
     9         c2 = man.getClass();
    10         try {
    11             c3 = Class.forName("cc.lijingbo.script.reflect.Man");
    12         } catch (ClassNotFoundException e) {
    13             e.printStackTrace();
    14         }
    15 
    16         System.out.println("类的名称:" + c1.getName());
    17         System.out.println("类的名称:" + c2.getName());
    18         System.out.println("类的名称:" + c3.getName());
    19     }
    20 }

    结果:

    类的名称:cc.lijingbo.script.reflect.Man
    类的名称:cc.lijingbo.script.reflect.Man
    类的名称:cc.lijingbo.script.reflect.Man

    3. Class 类实例化 Man 类,通过 Man 类的无参构造方法

     1 public class ReflectTest {
     2     public static void main(String[] args) {
     3         Class<?> c3 = null;
     4         try {
     5             c3 = Class.forName("cc.lijingbo.script.reflect.Man");
     6         } catch (ClassNotFoundException e) {
     7             e.printStackTrace();
     8         }
     9         try {
    10             Man man = (Man) c3.newInstance();
    11             man.say();
    12             man.eat();
    13             man.sleep();
    14         } catch (InstantiationException e) {
    15             e.printStackTrace();
    16         } catch (IllegalAccessException e) {
    17             e.printStackTrace();
    18         }
    19     }
    20 }

    结果:

    I am Man
    Man eat 5 breads
    Man need sleep 8 hours

    [注意]:假如类中定义了构造方法,且没有无参构造方法,使用 newInstance() 会报错,无法实例化。

    Man.java 去掉无参构造方法,然后使用 Class 类实例化 Man 类

    Test.java

     1 public class ReflectTest {
     2     public static void main(String[] args) {
     3         Class<?> c3 = null;
     4         try {
     5             c3 = Class.forName("cc.lijingbo.script.reflect.Man");
     6         } catch (ClassNotFoundException e) {
     7             e.printStackTrace();
     8         }
     9         try {
    10             Man man = (Man) c3.newInstance();
    11             man.say();
    12             man.eat();
    13             man.sleep();
    14         } catch (InstantiationException e) {
    15             e.printStackTrace();
    16         } catch (IllegalAccessException e) {
    17             e.printStackTrace();
    18         }
    19     }
    20 }
     

    结果:

     1 java.lang.InstantiationException: cc.lijingbo.script.reflect.Man
     2     at java.lang.Class.newInstance(Class.java:423)
     3     at cc.lijingbo.script.reflect.ReflectTest.main(ReflectTest.java:15)
     4     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     5     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
     6     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
     7     at java.lang.reflect.Method.invoke(Method.java:483)
     8     at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
     9 Caused by: java.lang.NoSuchMethodException: cc.lijingbo.script.reflect.Man.<init>()
    10     at java.lang.Class.getConstructor0(Class.java:3074)
    11     at java.lang.Class.newInstance(Class.java:408)
    12     ... 6 more

    分析:

    可以看到异常的是原因: Caused by: java.lang.NoSuchMethodException: cc.lijingbo.script.reflect.Man.<init>(),并重新抛出了 java.lang.InstantiationException的异常。引起的原因就是没有无参构造方法造成的。

    4. 调用 Man 类中的所有构造方法,可以通过各种构造方法实例化 Man 类。

     [注意]:反射获取到的所有构造方法中,注意在数组中的顺序。

    Test.java

     1 public class ReflectTest {
     2     public static void main(String[] args) {
     3         Class<?> c = null;
     4         try {
     5             c = Class.forName("cc.lijingbo.script.reflect.Man");
     6         } catch (ClassNotFoundException e) {
     7             e.printStackTrace();
     8         }
     9         Man m1 = null;
    10         Man m2 = null;
    11         Man m3 = null;
    12         Man m4 = null;
    13         Constructor<?>[] constructors = c.getConstructors();
    14         try {
    15             m1 = (Man) constructors[3].newInstance();
    16             m2 = (Man) constructors[2].newInstance("Jerome");
    17             m3 = (Man) constructors[1].newInstance(20);
    18             m4 = (Man) constructors[0].newInstance("Jerome1", 21);
    19         } catch (InstantiationException e) {
    20             e.printStackTrace();
    21         } catch (IllegalAccessException e) {
    22             e.printStackTrace();
    23         } catch (InvocationTargetException e) {
    24             e.printStackTrace();
    25         }
    26         System.out.println(m1);
    27         System.out.println(m2);
    28         System.out.println(m3);
    29         System.out.println(m4);
    30     }
    31 }

    结果:

    null:0
    Jerome:0
    null:20
    Jerome1:21

    5. 获得 Man 类中的全部构造函数

     1 public class ReflectTest {
     2     public static void main(String[] args) {
     3         Class<?> c = null;
     4         try {
     5             c = Class.forName("cc.lijingbo.script.reflect.Man");
     6         } catch (ClassNotFoundException e) {
     7             e.printStackTrace();
     8         }
     9         Constructor<?>[] constructors = c.getConstructors();
    10         for (Constructor constructor : constructors) {
    11             System.out.println(constructor);
    12         }
    13     }
    14 }

    结果:

    1 public cc.lijingbo.script.reflect.Man(java.lang.String,int)
    2 public cc.lijingbo.script.reflect.Man(int)
    3 public cc.lijingbo.script.reflect.Man(java.lang.String)
    4 public cc.lijingbo.script.reflect.Man()

     

    6. 返回类实现的接口

     1 public class ReflectTest {
     2     public static void main(String[] args) {
     3         Class<?> c = null;
     4         try {
     5             c = Class.forName("cc.lijingbo.script.reflect.Man");
     6         } catch (ClassNotFoundException e) {
     7             e.printStackTrace();
     8         }
     9         Class<?>[] interfaces = c.getInterfaces();
    10         for (Class in : interfaces) {
    11             System.out.println(in.getName());
    12         }
    13     }
    14 }

    结果:

    cc.lijingbo.script.reflect.Person

    7. 取得 Child 类的父类

    Child.java

    1 public class Child extends Man {
    2 
    3     @Override
    4     public void say() {
    5         System.out.println("I am Child");
    6     }
    7 }

    Test.java

     1 public class ReflectTest {
     2     public static void main(String[] args) {
     3         Class<?> c = null;
     4         try {
     5             c = Class.forName("cc.lijingbo.script.reflect.Child");
     6         } catch (ClassNotFoundException e) {
     7             e.printStackTrace();
     8         }
     9         Class<?> superclass = c.getSuperclass();
    10         System.out.println(superclass.getName());
    11     }
    12 }

    结果:

    cc.lijingbo.script.reflect.Man

    8.  获取构造方法的修饰符

     1 public class ReflectTest {
     2     public static void main(String[] args) {
     3         Class<?> c = null;
     4         try {
     5             c = Class.forName("cc.lijingbo.script.reflect.Man");
     6         } catch (ClassNotFoundException e) {
     7             e.printStackTrace();
     8         }
     9         Constructor<?>[] constructors = c.getConstructors();
    10         for (int i = 0; i < constructors.length; i++) {
    11             Class[] parameterTypes = constructors[i].getParameterTypes();
    12             int modifiers = constructors[i].getModifiers();
    13             System.out.print(Modifier.toString(modifiers) + " ");
    14             System.out.print(constructors[i].getName());
    15             System.out.println("(");
    16             for (int j = 0; j < parameterTypes.length; ++j) {
    17                 System.out.print(parameterTypes[j].getName() + " arg" + i);
    18                 if (j < parameterTypes.length - 1) {
    19                     System.out.print(",");
    20                 }
    21             }
    22             System.out.println("){}");
    23         }
    24     }
    25 }

    结果:

    1 public cc.lijingbo.script.reflect.Man(
    2 java.lang.String arg0,int arg0){}
    3 public cc.lijingbo.script.reflect.Man(
    4 int arg1){}
    5 public cc.lijingbo.script.reflect.Man(
    6 java.lang.String arg2){}
    7 public cc.lijingbo.script.reflect.Man(
    8 ){}

    9. 取得 Man 类的全部属性

     1 public class ReflectTest {
     2     public static void main(String[] args) {
     3         Class<?> c = null;
     4         try {
     5             c = Class.forName("cc.lijingbo.script.reflect.Man");
     6         } catch (ClassNotFoundException e) {
     7             e.printStackTrace();
     8         }
     9         Field[] declaredFields = c.getDeclaredFields();
    10         for (Field field : declaredFields) {
    11             int modifiers = field.getModifiers();
    12             String type = Modifier.toString(modifiers);
    13             Class<?> fieldType = field.getType();
    14             System.out.println(type + " " + fieldType + " " + field.getName());
    15         }
    16         System.out.println("..........");
    17         Field[] fields = c.getFields();
    18         for (Field field : fields) {
    19             int modifiers = field.getModifiers();
    20             String type = Modifier.toString(modifiers);
    21             Class<?> fieldType = field.getType();
    22             System.out.println(type + " " + fieldType + " " + field.getName());
    23         }
    24     }
    25 }

    结果:

    private class java.lang.String name
    private int age
    ..........
    public static final class java.lang.Boolean isMale

    10.调用 Man 类中的方法,有参方法,无参方法,静态无参方法和静态有参方法

     1 public class ReflectTest {
     2     public static void main(String[] args) {
     3         Class<?> c = null;
     4         try {
     5             c = Class.forName("cc.lijingbo.script.reflect.Man");
     6         } catch (ClassNotFoundException e) {
     7             e.printStackTrace();
     8         }
     9 
    10         //调用带参的方法
    11         try {
    12             Method sayName = c.getMethod("sayName", String.class);
    13             sayName.invoke(c.newInstance(), "Jerome");
    14         } catch (NoSuchMethodException e) {
    15             e.printStackTrace();
    16         } catch (IllegalAccessException e) {
    17             e.printStackTrace();
    18         } catch (InstantiationException e) {
    19             e.printStackTrace();
    20         } catch (InvocationTargetException e) {
    21             e.printStackTrace();
    22         }
    23 
    24         //调用无参的方法
    25         try {
    26             Method say = c.getMethod("say");
    27             say.invoke(c.newInstance());
    28         } catch (NoSuchMethodException e) {
    29             e.printStackTrace();
    30         } catch (IllegalAccessException e) {
    31             e.printStackTrace();
    32         } catch (InstantiationException e) {
    33             e.printStackTrace();
    34         } catch (InvocationTargetException e) {
    35             e.printStackTrace();
    36         }
    37 
    38         //调用静态无参方法
    39         try {
    40             Method sayStatic = c.getMethod("sayStatic");
    41             sayStatic.invoke(null);
    42         } catch (NoSuchMethodException e) {
    43             e.printStackTrace();
    44         } catch (InvocationTargetException e) {
    45             e.printStackTrace();
    46         } catch (IllegalAccessException e) {
    47             e.printStackTrace();
    48         }
    49 
    50         //调用静态带参方法
    51         try {
    52             Method sayStatic2 = c.getMethod("sayStatic2", String.class);
    53             sayStatic2.invoke(null,"Jerome");
    54         } catch (NoSuchMethodException e) {
    55             e.printStackTrace();
    56         } catch (InvocationTargetException e) {
    57             e.printStackTrace();
    58         } catch (IllegalAccessException e) {
    59             e.printStackTrace();
    60         }
    61 
    62     }
    63 }

    结果:

    I am Jerome
    I am Man
    This is a static method
    This is a static method,I am Jerome

    11. 获取到 Man 类所有的方法,及方法的修饰符,返回值和参数

     1 public class ReflectTest1 {
     2     public static void main(String[] args) {
     3         Class<?> c = Man.class;
     4         Method[] methods = c.getDeclaredMethods();
     5         for (Method method : methods) {
     6             StringBuffer sb = new StringBuffer();
     7             //获取到方法的修饰符
     8             String modifier = Modifier.toString(method.getModifiers());
     9             sb.append(modifier + " ");
    10             Class<?> methodReturnType = method.getReturnType();
    11             //获取到方法的返回类型,没有返回值时为null
    12             String returnType = methodReturnType.getName();
    13             String methodName = method.getName();
    14             if (returnType == null) {
    15                 sb.append("void ");
    16             } else {
    17                 sb.append(returnType + " ");
    18             }
    19             sb.append(methodName).append("(");
    20             Class<?>[] parameterTypes = method.getParameterTypes();
    21             for (Class parameter : parameterTypes) {
    22                 String name = parameter.getName();
    23                 sb.append(name).append(",");
    24             }
    25             sb.append(")");
    26             System.out.println(sb.toString());
    27         }
    28     }
    29 }

    结果:

    public java.lang.String toString()
    public void sleep()
    public void say()
    private java.lang.String test1(java.lang.String,int,)
    public static void sayStatic()
    public void eat()
    public void sayName(java.lang.String,)
    public static void sayStatic2(java.lang.String,)

    12. 获取到类加载器

     1 public class ReflectTest2 {
     2     public static void main(String[] args) {
     3         Class<?> c = Man.class;
     4         //获取到 classloader
     5         ClassLoader classLoader = c.getClassLoader();
     6         //通过获取到classloader的类类型,得到classloader的名称
     7         String name = classLoader.getClass().getName();
     8         System.out.println(name);
     9     }
    10 }

    结果:

    sun.misc.Launcher$AppClassLoader

    13. 修改成员变量的值

     1 public class ReflectTest3 {
     2     public static void main(String[] args) {
     3         Class<?> c = Man.class;
     4         try {
     5             Field name = c.getDeclaredField("name");
     6             name.setAccessible(true);
     7             Object o = c.newInstance();
     8             name.set(o,"Haha");
     9             System.out.println(name.get(o));
    10         } catch (NoSuchFieldException e) {
    11             e.printStackTrace();
    12         } catch (InstantiationException e) {
    13             e.printStackTrace();
    14         } catch (IllegalAccessException e) {
    15             e.printStackTrace();
    16         }
    17     }
    18 }

    结果:

    Haha

    14. 获取数组相关信息

     1 public class ReflectTest4 {
     2     public static void main(String[ ] args){
     3         int[] temp = {1,2,4,5,7};
     4         Class<?> c = temp.getClass();
     5         Class<?> componentType = c.getComponentType();
     6         System.out.println("数组的类型:"+componentType.getName());
     7         System.out.println("数组的长度:"+Array.getLength(temp));
     8         System.out.println("数组第三个位置:"+Array.get(temp,2));
     9         Array.set(temp,2,44);
    10         System.out.println("修改后的数组第三个位置:"+Array.get(temp,2));
    11     }
    12 }

    结果:

    数组的类型:int
    数组的长度:5
    数组第三个位置:4
    修改后的数组第三个位置:44
  • 相关阅读:
    团队开发冲刺第十五天
    团队开发冲刺第十四天
    团队开发冲刺第十三天
    团队开发冲刺第十二天
    团队开发冲刺第十一天
    团队开发冲刺第十天
    幸运抽奖案例
    java中如何数组是如何赋值的?
    使用java中的String类操作复杂的字符串
    java中随机生成26个字母组合的随机验证码
  • 原文地址:https://www.cnblogs.com/liyiran/p/5803321.html
Copyright © 2020-2023  润新知