zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    head命令
    less命令
    解决get方法传递URL参数中文乱码问题
    The method convert(String) of type DateConverter must override a superclass method
    Tomcat Can't load AMD 64-bit .dll on a IA 32
    聚合函数查询 group by having
    string[] 清理重复+反转显示
    C# GetValueList 获得字符串中开始和结束字符串中间得值列表
    C# GetValue 正则获取开始结束代码
    string [] 去除重复字符两个方法
  • 原文地址:https://www.cnblogs.com/L-o-g-i-c/p/11697384.html
Copyright © 2011-2022 走看看