java反射
Java反射
1、何为反射? 简而言之: 加载类,并解剖出类的各个组成部分。根据java语言的这一特性,可将Java视为一种动态语言。更好的理解反射机制有助于我们深层次的理解spring框架。
2、Class类 代表了一个类的字节码。 在 java.lang包中可以找到。
加载字节码的方法:
1 Class.forName("全类名"); Class.forName("com.mysql.jdbc.Driver");
该方法的作用是,加载某个类的字节码到内存中,并使用class对象进行封装。
3、如何获取class对象?下面用Demos.java来举例
 1 package org.reflect.test;
 2 
 3 public class Demos implements Serializable {
 4     
 5     public String demoName0;
 6     public String demoName2;
 7     public String demoName3;
 8     private String demotype0;
 9     private String demotype1;
10     private String demotype2;
11     
12     public Demos(){}
13     
14     //构造函数
15     public Demos(String name, String type) {
16         
17     }
18     
19     //私有方法
20     private void getDemoName0(){
21         
22         
23     }
24     private void setDemoName1(){
25         
26         
27     }
28     private void setDemoName2(){
29         
30         
31     }
32     
33     //共有方法
34     public void getDemoType0(){
35         
36         
37     }
38     public void getDemoType1(){
39         
40         
41     }
42     public void getDemoType2(){
43         
44         
45     }
46     
47     //测试方法
48     public void sayHello(String s){
49         
50         System.out.println("Public Hello"+s);
51     }
52     
53     //测试方法
54     private void sayPrivateHello(String s){
55         
56         System.out.println("Private Hello"+s);
57     }
58     
59 }
获取方式:
1      //获取class类方式1
2         Class clazz1=Class.forName("org.reflect.test.Demos");
3         //方式2
4         Class clazz2=Demos.class;
5         //方式3
6         Class clazz3=new Demos().getClass();
4、获取包名,全类名,类的修饰符,父类,接口名,构造方法
 1 //获取包名包名
 2         String package1=clazz1.getPackage().getName();
 3         String package2=clazz2.getPackage().getName();
 4         
 5         System.out.println("包名1 :"+package1+"---包名2 :"+package2);
 6         
 7         //获取类全名
 8         String name1=clazz1.getName();
 9         String name2=clazz2.getName();
10         System.out.println("类名1 :"+name1+"---类名2 :"+name2);
11         
12         //获取类的修饰符
13         int mod=clazz1.getModifiers();
14         System.out.println("该类的修饰符 :"+Modifier.toString(mod));
15         
16         //获取该类的父类
17         Class supercla=clazz1.getSuperclass();
18         System.out.println("父类 :"+supercla);
19         
20         //获得该类的接口
21         Class []interfaces=clazz1.getInterfaces();
22         for (Class i:interfaces) {
23             System.out.println("接口名  :" + i.getName());
24         }
25         
26         
27         //获取该类的构造方法
28         Constructor []con=clazz1.getConstructors();
29         for (Constructor c :con) {
30             System.out.println("构造函数名 :"+c.getName());
31         }
32         
输出结果:
 
 
5、获取该类的字段的两种方法:
getFields();
getDeclaredFields();
 1         //获取该类的字段 ,只限public修饰符修饰的
 2         Field[]fils=clazz1.getFields();
 3         for (Field f :fils) {
 4             System.out.println("fieldsName :"+f.getName());
 5         }
 6         //获取该类的所有的字段,public, protected, default(package) access, and private fields
 7         //不包括继承来的属性
 8         Field []filss=clazz1.getDeclaredFields();
 9         for (Field f :filss) {
10             System.out.println("DeclaredFields :"+f.getName());
11         }
说明:getFields();该方法只获取本类中public修饰的属性,
getDeclaredFileds();该方法获取该类中所有的属性,包括私有,但是不包括继承来的属性。
输出结果:
 
 
6、获取该类的方法的两种方法:
getMethods();
getDeclaredMethods();
 1 //获取该类的特定的方法 public,包括父类的以及接口实现的
 2         Method[]methods=clazz1.getMethods();
 3         for(Method m:methods){
 4             System.out.println("Methods :"+m.getName());
 5         }
 6         
 7         //获取所有的方法,public private 仅限当前类,不包括父类
 8         Method []method3=clazz1.getDeclaredMethods();
 9         for(Method m : method3){
10             System.out.println("DeclaredMethods :"+m.getName());
11         }
说明:getMethods();获取该类public修饰的方法,包括父类及接口实现的
getDeclaredMethods();只获取本类中的所有方法,包括private修饰的
输出结果:
 
 
7、通过反射调用Demos类中的方法
 1      //获得该类的一个实例
 2         Demos c=(Demos) clazz2.newInstance();
 3         Method  method=clazz2.getMethod("sayHello", String.class);
 4         method.invoke(c, "World!!!");
 5         
 6         //getDeclaredMethod能获取到所有定义的方法。setAccessible方法为true 则可以访问到私有的方法
 7         Demos c2=(Demos) clazz1.newInstance();
 8         Method method2=clazz1.getDeclaredMethod("sayPrivateHello", String.class);
 9         method2.setAccessible(true);
10         method2.invoke(c2, "World!!!!");
说明:getMethod("arg0","arg1"); arg0代表方法的名称,arg1代表参数的类型。
getDeclaredMethod("arg2","arg3"); arg2,arg3的含义同getMethod方法。
输出结果:
 
 
这里有一个小插曲,都知道私有的方法只能供本类使用,属于本类私有,但是这里我们可以看到利用反射可以访问到Demos类中的私有方法,所以下次面试遇到private修饰的方法能被其他类调用吗?就可以说利用反射是可以的 0.0
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号