反射

什么是java反射机制?
当程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言。我们认为java并不是动态语言,但是它却有一个非常突出的动态相关机制,俗称:反射。

一、Class类

什么是Class类?
在面向对象的世界里,万事万物皆是对象。而在java语言中,static修饰的东西不是对象,但是它属于类。
普通的数据类型不是对象,例如:int a = 5;它不是面向对象,但是它有其包装类 Integer 或者封装类来弥补了它。除了以上两种不是面向对象,其余的封装类也有它的面向对象,所有类都是java.lang.Class类的实例化对象(注意Class是大写)。也就是说:
Class A{}
当我创建了A类,那么类A本身就是一个对象,谁的对象?java.lang.Class的实例对象。

二、获取Class类

在应用反射机制之前,首先我们先来看一下如何获取一个对象对应的反射类Class,在Java中我们有三种方法可以获取一个对象的反射类。

通过getClass方法

在Java中,每一个Object都有一个getClass()方法,通过getClass方法我们可以获取到这个对象对应的反射类:

ListTest listTest = new ListTest();
Class<?> clazz = listTest.getClass();
System.out.println(clazz.getName());
通过forName方法

我们也可以调用Class类的静态方法forName():

Class<?> clas = Class.forName("com.github.chengbin.auth.ListTest");
System.out.println(clas.getName());
使用T.class

或者我们也可以直接使用.class:

Class<?> c = People.class;

三、实例化Class类

获取到Class类之后,调用newInstance()可以实例化该类,获取该类的一个实例:

ListTest listTest = new ListTest();
Class<?> clazz = listTest.getClass();
System.out.println(clazz.getName());
ListTest listTest1 = (ListTest)clazz.newInstance();

四、Class类信息

class类里面有很多方法,通过这些方法可以获取类的详细信息,包括类名称、修饰符、父类、类加载器、类方法、类变量等;

try {
    Class clas = Class.forName("com.github.chengbin.auth.ListTest");
    System.out.println("name:" +clas.getName() + ",simpleName:" + clas.getSimpleName()
            + ",superClass:" +clas.getSuperclass() +",modifiers:" + clas.getModifiers() +
            ",classLoader:" + clas.getClassLoader());
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}

打印:

name:com.github.chengbin.auth.ListTest
simpleName:ListTest
superClass:class java.lang.Object
modifiers:1
classLoader:sun.misc.Launcher$AppClassLoader@190d0630

public String getName() 方法:获取类的全路径类(包括包名),返回的是String类型

public String getSimpleName()方法:获取类的名称

Class<? super T> getSuperclass()方法:获取父类,返回的是Class类型

public ClassLoader getClassLoader():返回类的类加载器

public Field[] getDeclaredFields():返回该类申明的变量

public Method[] getDeclaredMethods():返回该类申明的方法,不包括从Object类继承过来的方法,如:toString、HashCode()、wait()等;

public Method[] getMethods():返回该类的所有的方法;

public Annotation[] getAnnotations():返回该类的所有注解

public native Class<?>[] getInterfaces():返回该类所实现的所有接口

public Constructor<?>[] getDeclaredConstructors():返回该类的构造器

public native int getModifiers()方法:返回类修饰符,该修饰符是java.lang.reflect.Modifier的静态属性。
对应表如下:

PUBLIC: 1
PRIVATE: 2
PROTECTED: 4
STATIC: 8
FINAL: 16
SYNCHRONIZED: 32
VOLATILE: 64
TRANSIENT: 128
NATIVE: 256
INTERFACE: 512
ABSTRACT: 1024
STRICT: 2048

五、Method信息

class通过getMethods()可以获取该类的所有方法,返回的是Method[]method数组:
Class<?> clas = Class.forName(“com.github.chengbin.auth.ListTest”);

Mehtod类里面有很多好用的方法,可以获取的类的方法的具体信息。
getName() 方法:获取方法名称

getModifiers()方法:获取方法的修饰符类型

public Class<?> getReturnType():获取方法的返回值类型

public Class<?>[] getExceptionTypes():获取方法抛出的异常的类型

public Class<?>[] getParameterTypes():获取方法的参数类型

public Annotation[] getAnnotations():获取方法的所有注解类型

举个栗子:

for (Method method : clas.getMethods()) {
    System.out.println("name:" +method.getName() + "\nmodifiers:" + method.getModifiers()
            + "\nreturnType:" +method.getReturnType() +"\nexceptionTypes:" + method.getExceptionTypes() +
            "\nparameterTypes:" + method.getParameterTypes() + "\nannotations:" + method.getAnnotations());
    RateLimiter rateLimiter = method.getAnnotation(RateLimiter.class);
    if(rateLimiter != null){
        System.out.println("注解RateLimiter");
    }
}

打印:

name:getInstance
modifiers:9
returnType:class java.lang.Object
exceptionTypes:[Ljava.lang.Class;@11dea651
parameterTypes:[Ljava.lang.Class;@30791901
annotations:[Ljava.lang.annotation.Annotation;@363f983f
注解RateLimiter

六、Field

class通过getDeclaredFields()可以获取该类申明的变量,返回的是Field[]Field数组:

Class<?> clas = Class.forName("com.github.chengbin.auth.ListTest");
Field[] fields = clas.getDeclaredFields();

Field类里面有很多好用的方法,可以获取的类的变量或者方法参数的具体信息。

for (Field field : fields) {
    System.out.println("申明的变量:"+field.getName());
    System.out.println("name:" +field.getName() + "\ntype:" + field.getType()
            + "\ncount:" +field.getInt("count") +"\nmodifiers:" + field.getModifiers());
}

getName():变量的名称

getModifiers():变量的修饰符

public Annotation[] getAnnotations():返回变量的注解

public Class<?> getType():变量的类型

     反射虽然很强大,但是大量的使用反射会影响程序的性能,所以合理利用反射非常重要!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值