java中的反射

java的反射

反射小结

Class:是一个类;一个描述类的类

Method:是一个描述方法的类;

Filed:是一个描述字段的类;

Constructor:是一个描述构造器的类;

1.得到Class对象的三种方法

  • Class clazz = 类名.class;
  • Class clazz = 对项目.getClass();
  • Class clazz = Class.forName("全类名");

2.获取Method:

  • getMethods():不能获取私有的方法,但是可以获取到所继承的方法;
  • getDeclaredMethods():不能获取到继承的方法;私有方法要跳过验证
  • getDeclaredMethod(String methondName,Class … parameterTypes):获取单个方法,如果有参数则需要传入参数

3.执行Method:

  • 如果调用的方法是私有的话就需要跳过安全验证setAccessible(true);
  • method.invoke(obj,Object … args);

4.获取Field:

  • getFields():不能获取私有的字段,但是可以获取到所继承的字段;
  • getDeclaredFields():不能获取到继承的字段;私有字段要跳过验证
  • getDeclaredField(String fieldName):获取单个字段

5.获取Field的值:

  • 私有的字段就需要跳过安全检查setAccessible(true);
  • field.get(obj);

6.设置Field的值:

  • 私有字段跳过安全验证
  • filed.set(obj,value);
  1.  

7.获取构造器:

  • getConstructors();获取所有构造器;
  • getConstructor(Class<?>...parameterTypes);获取单个构造器(可以获取带参构造器)

8.通过构造器创建实例

  • constructor.newInstance();如果有参数则获取有参构造器把参数传入即可
  1.  

9.反射获取父类的泛型

  • getGenericSuperClass():获取到带泛型的父类
  • Type是一个空的接口,是用的时候要使用他的子接口ParameterizedType
  • 调用getActualTypeArguments()返回父类的泛型数组

10.反射的概述

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性,也可以得到这个类实现了那些接口;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

对于每一个类而言,JRE都为其保留了一个不变的Class类形的对象。一个Class对象包含了特定某个类的有关信息。

-class对想只能有系统创建对象

-一个类在jvm中只会有一个Class的实列

-每一个类的实例都会记得自己是有哪一个Class实力所生成的。

1.1常用的工具类

Class类

java的类加载机制

ClassLoader类加载器

Constructor 、Method、Field(字段)

native(本地的)关键字,这个是修饰方法是一个原生态的方法,方法的实现不是当前的文件,而是使用其他的语言实现在文件中。java原因本身是无法对系统底层进行访问和操作的,但是可以通过JNI接口调用其它的语言来实现对底层的访问。

2.反射的使用

是用到的类:

Person:

Student:

Person(接口):

Emp(泛型):

1.获取类的三种方式

 

通过这三种方法获取到的Class是同一个,都是相等的.

2.通过Class创建对象

 

3.获取对象的所有的方法

/1.获取类里面的方法,可以获取到接口的,继承的,但是无法获取私有的方法;

/2.获取到当前这个类的所以的方法,所有声明的方法,都可以获取到,且只获取当前类的方法,也可以获取到接口实现的方法,但是不能获取到继承的方法

注意,执行一个私有的方法的时候需要跳过安全验证

 1         package reflect;
 2         
 3         import entity.Person;
 4         
 5         import java.lang.reflect.InvocationTargetException;
 6         import java.lang.reflect.Method;
 7         
 8         /**
 9         *Description:java_project
10         *CreatedbySMO992079on2019/6/1112:48
11         */
12         public class ReflectGetMetHods{
13         
14             private static Class clazz;
15             
16             static{
17                 try{
18                     clazz=Class.forName("entity.Person");
19                 }catch(ClassNotFoundExceptione){
20                     e.printStackTrace();
21                 }
22             }
23             
24             public static void testMethod(){
25                 //1.获取类里面的方法,可以获取到接口的,继承的,但是无法获取私有的方法;
26                 Method[] methods = clazz.getMethods();
27                 for(Methodmethod:methods){
28                     System.out.print(" "+method.getName());
29                 }
30                 System.out.println();
31                 
32                 //2.获取到当前这个类的所以的方法,所有声明的方法,都可以获取到,且只获取当前类的方法,也可以获取到接口实现的方法,但是不能获取到继承的方法
33                 Method[] declaredMethods = clazz.getDeclaredMethods();
34                 for(Method method:declaredMethods){
35                     System.out.print(""+method.getName());
36                 }
37                 System.out.println();
38                 
39                 //3.获取一个指定的方法,如果有参数的话需要穿一个参数类型例如privatevoidchangeName(Stringname)
40                 MethodchangeName=null;
41                 try{
42                     //通过getMethod()这个方法是获取不到私有的方法的。回报java.lang.NoSuchMethodException这个错误
43                     //changeName=clazz.getMethod("changeName",String.class);
44                     changeName=clazz.getDeclaredMethod("changeName",String.class);
45                     changeName.setAccessible(true);//私有方法的加必须跳过安全验证
46                     System.out.println(changeName);
47                 }catch(NoSuchMethodExceptione){
48                     e.printStackTrace();
49                 }
50                 //4.执行一个方法
51                 try{
52                     Person o = (Person)clazz.newInstance();
53                     changeName.invoke(o,"张三");
54                     System.out.println(o.getName());
55                 }catch(InstantiationExceptione){
56                     e.printStackTrace();
57                 }catch(IllegalAccessExceptione){
58                     e.printStackTrace();
59                 }catch(InvocationTargetExceptione){
60                     e.printStackTrace();
61                 }
62                 
63             
64             }
65             
66             public static void main(String[]args){
67                 testMethod();
68             }
69         }

4.获取对象的所有的字段

 1 public static void testgetFiled(){
 2 
 3   //1.获取本类的所有的字段,但是无法获取到父类的字段
 4 
 5   Field[] declaredFields=clazz.getDeclaredFields();
 6 
 7   for(Fieldfield:declaredFields){
 8 
 9   System.out.println(field.getName());
10 
11   }
12 
13  
14 
15   //2.获取指定的字段
16 
17   Field name=null;
18 
19   try{
20 
21     name=clazz.getDeclaredField("name");
22 
23     System.out.println(name.getName());
24 
25   }catch(NoSuchFieldExceptione){
26 
27     e.printStackTrace();
28 
29   }
30 
31   //3.使用字段
32 
33   Person person=newPerson("张三",18);
34 
35   name.setAccessible(true);//跳过安全验证
36 
37   try{
38 
39     Objecto=name.get(person);
40 
41     System.out.println(o);
42 
43   }catch(IllegalAccessExceptione){
44 
45     e.printStackTrace();
46 
47   }
48 
49   //3.1给一个字段复制
50 
51   try{
52 
53     name.set(person,"李四");
54 
55     System.out.println(name.get(person));
56 
57   }catch(IllegalAccessExceptione){
58 
59     e.printStackTrace();
60 
61   }
62 
63 }

5.获取一个类的构造器

 1 Public static void testgetConstructors()throws NoSuchMethodException,IllegalAccessException,InvocationTargetException,InstantiationException{
 2 
 3 //1.获取本类所有的构造器
 4 
 5 Constructor[] constructors=clazz.getConstructors();
 6 
 7 for(Constructor constructor :constructors ){
 8 
 9 System.out.println(constructor);
10 
11 }
12 
13 //2.获取指定的构造器
14 
15 Constructor<Person>constructor=clazz.getConstructor();
16 
17  
18 
19 //2.1获取指定带参数的构造器
20 
21 Constructor<Person>constructor1=clazz.getConstructor(String.class,int.class);
22 
23  
24 
25 //3.通过构造器来创建对象
26 
27 Personperson=constructor.newInstance();
28 
29 System.out.println(person);
30 
31  
32 
33 //3.1通过有参数的构造器来创建对象
34 
35 Personperson1=constructor1.newInstance("张三",18);
36 
37 System.out.println(person1.getName());
38 
39 }

6.获取父类的泛型

 1 public static void testAnnotation(){
 2 
 3 //获取带泛型的子类
 4 
 5 Type type=clazz.getGenericSuperclass();
 6 
 7 System.out.println(type);//entity.Student<entity.Emp>
 8 
 9 //此时获得了泛型参数,然后就是把它提取出来
10 
11 //注意Type是一个空的接口,这里使用它的子类ParameterizedType,表示带参数的类类型(即泛型)
12 
13 Class clazzs=null;
14 
15 if(typeinstanceofParameterizedType){
16 
17    ParameterizedType parameterizedType=(ParameterizedType)type;
18 
19    Type[] actualTypeArguments=parameterizedType.getActualTypeArguments();
20 
21   for(Typetypes:actualTypeArguments){
22 
23     System.out.println(types);
24 
25     clazzs=(Class<?>)types;
26 
27   }
28 
29 }
30 
31 System.out.println(clazzs);
32 
33 }
原文地址:https://www.cnblogs.com/L-o-g-i-c/p/11697384.html