美文网首页
咱们一起来探讨Java的反射吧

咱们一起来探讨Java的反射吧

作者: 墨源为水 | 来源:发表于2016-06-15 22:14 被阅读205次

    一.为什么使用反射?反射是什么?

    反射可以解决在编译时无法预知对象和类是属于那个类的,要根据程序运行时的信息才能知道该对象和类的信息的问题。在两个人协作开发时,你只要知道对方的类名就可以进行初步的开发了。

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

    二.从案例学习如何使用反射

    public class Man implements AnimalBaseSkill{
        
        public int sex=-1;    
        private String name;    
        private Man(int sex, String name) {      
            this.sex = sex;        
            this.name = name;    
        }    
        public Man() {         
        }    
        public int getSex() {        
            return sex;    
        }    
        public void setSex(int sex) {        
            this.sex = sex;    
        }    
        public String getName() {        
            return name;    
        }    
        public void setName(String name) {        
            this.name = name;    
        }
    
        @Override
        public void eat() {}
        
    
        private class Clan {    
            String clanName="default family";    
            public Clan(String familyName) {        
                this.clanName = familyName;    
            }    
            public Clan() {    
    
            }    
            public String getClanName() {        
                return clanName;    
            }    
            public void setClanName(String clanName) {        
                this.clanName = clanName;    
            }
        }
    }
    
    1.如何通过反射获取Person对象?
    1. Class.forName(String clazzName)静态方法
    • 调用类的class属性,Person.class返回的就是Person的class对象(推荐使用)
    • 调用某个对象的getClass()方法

    eg.

    Class class1 = Class.forName("com.ch.java.reflect.Man");
    Class class2 = Man.class;
    Class class3 =Man.getClass();
    

    但是只有方法一可以获取私有内部类:

    Class class_clan=Class.forName("com.ch.java.reflect.Man$Clan");
    

    获取Class后,然后通过Class获取构造器,通过newInstance()就可以获取该对象:

    Constructor constructor=class1.getConstructor(null); 
    Man man= (Man) constructor.newInstance();
    

    但是内部类的对象要像下面获取,原因会在(如何获取类构造器?)讲解

    Constructor constructor=class_clan.getConstructor(Man.class, String.class);
    Object family=constructor.newInstance(man, "123");
    
    2.如何获取类构造器?
    1. getConstructor(Class...parameterTypes):返回此Class对象对应类的带指定形参的public构造器,返回参数:Connstructor
    • getConstructors():返回此Class对象对应类的所有public构造器,返回参数:Constructor[]
    • getDeclaredConstructor(Class...parameterTypes):返回此class对象对应类的带指定参数的构造器,与构造器的访问权限无关,返回参数:Constructor[]
    • getDeclaredConstructors():返回此class对象对应类的所有构造器,与构造器的访问权限无关,返回参数:Constructor[]

    person对象的构造器获取很简单,但是person内部类的family对象的构造器如何获取?它的坑点在哪里呢?

    for (Constructor constructor1 : class_clan.getDeclaredConstructors()) {
        System.out.println(constructor1.toString());
    }
    打印:
    public com.ch.java.reflect.Man$Clan(com.ch.java.reflect.Man,java.lang.String)
    public com.ch.java.reflect.Man$Clan(com.ch.java.reflect.Man)
    
    3.获取类成员方法
    1. getMethod(String name,Class<?>...parameterTypes):返回此class对象对应类的带指定形参的public方法,返回参数:Method
    • Method[] getMethods():返回此class对象所表示的类的所有public方法
    • Method getDeclaredMethod(string name,Class<?>...parameterTypes):返回此class对象对应类的带指定形参的方法,与方法访问权限无关
    • Method[] getDeclaredMethods():返回此class对象对应类的全部方法,与方法的访问权限无关
    class_1.getMethods();
    class_1.getDeclaredMethods();
    for (Method method : methods) { 
         System.out.print(method.getName()+" "+method.getReturnType()+" "); 
         int i=0;  
         for (Class<?> aClass : method.getParameterTypes()) {
             i++; 
             System.out.print("params"+i+" "+aClass.toString()+" "); 
          }  
          System.out.print("\n");
    }
    打印:
    getName class java.lang.String
    setName void params1 class java.lang.String
    color void params1 int
    getSex int
    setSex void params1 int
    Disconnected from the target VM, address: '127.0.0.1:52500', transport: 'socket'wait void 
    wait void params1 long params2 int
    wait void params1 long
    equals boolean params1 class java.lang.Object *********toString class java.lang.String 
    hashCode int
    getClass class java.lang.Class
    notify void 
    notifyAll void
    
    4.获取类成员变量
    1. Field getField(String name):返回此class对象对应类的指定名称的public成员变量
    • getFields():返回此class对象对应类的所有public成员变量,返回参数:Field[]
    • getDeclaredField(String name):返回此class对象对应类的指定名称的成员变量,与成员变量访问权限无关。返回参数:Field
    • getDeclaredFields():返回此class对象对应类的全部成员变量,与成员变量的访问权限无关,返回参数:Field[]
    Field[] fields=class_1.getFields();
    Field[] fields=class_1.getDeclaredFields();
    for (Field field : fields) { 
        System.out.println(field.getName()+" "+field.getType());
    }
    打印:
    sex int
    age int
    
    5.其他

    获取该类内部类

    Class<?>[] getDeclaredClasses():返回该class队形对应类里包含的全部内部类
    

    获取该类对象所在的外部类

    Class<?> getDeclaringClass():返回该Class对象对应类所在的外部类
    

    获取该类对象对应类所实现的接口

    Class<?>[] getInterfaces():返回该Class对象对应类所实现的全部接口
    

    获取该类对象对应类所继承的父类

    Class<? super T> getSuperclass():返回该Class对象对应类的超类的Class对象
    

    获取该类对象对应类的修饰符、所在包、类名等基本信息

    int getModifiers():返回此类或接口的所有修饰符,修饰符由public、protected、private、final、static、abstract等对应的常量组成,返回的整数应使用Modifier工具类的方法来解码,才可以获取真是的修饰符
    
    Package getPackage():获取该类的包
    
    String getName():以字符串形式返回此CLass对象所表示的类的简称
    

    判断该类是否为接口、枚举、注解类型

    boolean isAnnotation():返回此class对象是否表示一个注解类型
    
    boolean isAnnotationPresent(Class<? extends Annotation>annotationClass):判断此Class对象是否使用类Annotation修饰
    
    boolean isAnonymousClass():返回此class对象是否是一个匿名类
    
    boolean isArray():返回此class对象是否表示一个数组类
    
    boolean isEnum():返回此class对象是否表示一个枚举
    
    boolean isInterface():返回此class对象是否表示一个接口
    
    boolean isInstance(Object obj):判断obj是否是此class对象的实例,该方法可以完全代替instanceof操作符
    

    相关文章

      网友评论

          本文标题:咱们一起来探讨Java的反射吧

          本文链接:https://www.haomeiwen.com/subject/rtdpdttx.html