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

 

posted @ 2016-08-24 15:56  熠然  阅读(274)  评论(0编辑  收藏  举报