Java 反射机制

java提供了一个反射库,通过其可以在运行中分析类的能力,即获取类对应的信息(定义的属性、方法等)

测试类

public class ReflectTestClass {
    public int num0;

    private int num1;

    private static int num2;

    private int sum;

    public ReflectTestClass() {

    }

    public ReflectTestClass(int num0,int num1) {
        this.num0 = num0;
        this.num1 = num1;
    }

    public void setNum0(int num0) {
        this.num0 = num0;
    }

    public int getNum0() {
        return num0;
    }

    public void setNum1(int num1) {
        this.num1 = num1;
    }

    public int getNum1() {
        return num1;
    }


    private void addition() {
        sum = num1+num0;
    }


    public int getSum() {
        return sum;
    }
}

1. Class类

要学习如何运用反射,首先要了解Class。在Java为程序运行时的所有对象维护了一个类型标识,这个信息跟随着对象所属的类。同时这些信息存储在Class类中。

获取Class对象有三种方法:

1. Object中的getClass()方法会返回Class的实例
    Class class1 = testClass.getClass();

2. 任意类型使用 .class
    Class class2 = ReflectTestClass.class;

3. Class的静态方法forName(String className)
    Class class3 = Class.forName("com.jsk.reflect_test.ReflectTestClass");
    注意:这里的名称应该包含报名及类名

注意:一个Class对象仅仅是表示一个类型,而不一定不是一个类,如:

Class class4 = int.class;

Class对象可以通过getName()获取对应类型的名称

String className = class1.getName();
System.out.println(className);

sysout:
com.jsk.reflect_test.ReflectTestClass

Class对象可以通过newInstance()获取对应类型的实例,前提是存在默认的构造方法,否则会抛出异常

ReflectTestClass testClass2 = (ReflectTestClass) class3.newInstance();

2. 常用的类

在利用反射的时候通常还会用到一下几个类:
Field、Method、Constructor、Modifier

2.1 Field

Class的对象可以通过调用方法获取getFields()或getDeclaredFields()方法获取类的属性,不同的是getFields()获取的是public修饰的,而或getDeclaredFields获取的是所有声明的属性。

Field[] fields = class3.getFields();
Field[] fields2 = class3.getDeclaredFields();

通过Field可以获取对应属性的名称、类型以及修饰符

for (int i = 0; i < fields2.length; i++) {
    Field field = fields2[i];
    Class type = field.getType();
    String typeName = type.getName();
    String name = field.getName();
    int modifierInt = field.getModifiers();
    boolean isPublic = Modifier.isPublic(modifierInt);
    String modifierStr = Modifier.toString(modifierInt);
    System.out.println("Field  name:"+name+" type:"+typeName+" modifier:"+modifierStr);
}


Field  name:num0 type:int modifier:public
Field  name:num1 type:int modifier:private
Field  name:num2 type:int modifier:private static
Field  name:sum  type:int modifier:private
getType() 返回属性对应的Class类型;
getName() 返回属性对应的名称;
getModifiers() 返回有个int型数据,可以Modifier的静态方法判断所声明的前缀
2.2 Constructor

对于一个Class对象,可以通过getConstructors()或getDeclaredConstructors()者获取类对应的构造方法,然后通过Constructor对象获取相应构造方法的信息

Constructor[] constructors = class3.getConstructors();
for (Constructor constructor : constructors) {
    String name = constructor.getName();

    int modifierInt = constructor.getModifiers();
    String modifierStr = Modifier.toString(modifierInt);

    Class[] paraClass = constructor.getParameterTypes();
    StringBuilder builder = new StringBuilder();

    for (Class paraClas: paraClass) {
        String pareName = paraClas.getName();
        builder.append(" "+pareName);
    }
    System.out.println("Method Name:"+name+" Modifiers:"+modifierStr+" ParameterTypes:"+builder.toString());
}

Method Name:com.jsk.reflect_test.ReflectTestClass Modifiers:public ParameterTypes:
Method Name:com.jsk.reflect_test.ReflectTestClass Modifiers:public ParameterTypes: int int
getName() 获取方法的名称
getModifiers() 获取方法声明的前缀
getParameterTypes() 获取参数的类型
2.3 Method

对于一个Class对象,可以通过getMethods()或getDeclaredMethods()者获取类对应声明的方法,然后通过Method对象获取相应构造方法的信息

Method[] methods = class3.getMethods();
for (int i = 0; i < methods.length; i++) {
    Method method = methods[i];
    String name = method.getName();

    int modifierInt = method.getModifiers();
    String modifierStr = Modifier.toString(modifierInt);

    Class returnType = method.getReturnType();
    String returnStr = returnType.getName();

    Class[] paraClass = method.getParameterTypes();
    StringBuilder builder = new StringBuilder();
    for (Class  paraClas: paraClass) {
        String pareName = paraClas.getName();
        builder.append(pareName);
    }
    System.out.println("Method Name:"+name+" Modifiers:"+modifierStr+" ReturnType:"+returnStr+" ParameterTypes:"+builder.toString());
}


Method Name:getSum    Modifiers:public ReturnType:int ParameterTypes:
Method Name:getNum0   Modifiers:public ReturnType:int ParameterTypes:
Method Name:getNum1   Modifiers:public ReturnType:int ParameterTypes:
Method Name:setNum0   Modifiers:public ReturnType:void ParameterTypes:int
Method Name:setNum1   Modifiers:public ReturnType:void ParameterTypes:int
Method Name:wait      Modifiers:public final ReturnType:void ParameterTypes:
Method Name:wait      Modifiers:public final ReturnType:void ParameterTypes:long int
Method Name:wait      Modifiers:public final native ReturnType:void ParameterTypes:long
Method Name:equals    Modifiers:public ReturnType:boolean ParameterTypes:java.lang.Object
Method Name:toString  Modifiers:public ReturnType:java.lang.String ParameterTypes:
Method Name:hashCode  Modifiers:public native ReturnType:int ParameterTypes:
Method Name:getClass  Modifiers:public final native ReturnType:java.lang.Class ParameterTypes:
Method Name:notify    Modifiers:public final native ReturnType:void ParameterTypes:
Method Name:notifyAll Modifiers:public final native ReturnType:void ParameterTypes:
getType() 返回属性对应的Class类型;
getName() 返回属性对应的名称;
getModifiers() 返回有个int型数据,可以Modifier的静态方法判断所声明的前缀
getReturnType() 获取返回值的类型
2.4 Modifier

对于Field、Method、Constructor通过方法getModifiers()获取的修饰语,返回的是一个int值,要获取其具体的信息可以通过Modifier的相关静态方法获取

static int      classModifiers()
static int      constructorModifiers()
static int      fieldModifiers()
static int      interfaceModifiers()
static boolean  isAbstract(int mod)
static boolean  isFinal(int mod)
static boolean  isInterface(int mod)
static boolean  isNative(int mod)
static boolean  isPrivate(int mod)
static boolean  isProtected(int mod)
static boolean  isPublic(int mod)
static boolean  isStatic(int mod)
static boolean  isStrict(int mod)
static boolean  isSynchronized(int mod)
static boolean  isTransient(int mod)
static boolean  isVolatile(int mod)
static int      methodModifiers()
static String   toString(int mod)

3. 属性操作

对于一个类的属性,同样可以利用反射机制对其操作

ReflectTestClass testClass = new ReflectTestClass();
Class cls = testClass.getClass();

Field field = cls.getDeclaredField("num1");
field.setAccessible(true);

field.set(testClass, 123);

int i = (int) field.get(testClass);
System.out.println(i);
在以上,ReflectTestClass类中声明有num1属性。首先获取其的Class对象,然后可以通过
  getField(String name)
或getDeclaredField(String name)方法获取相应的属性.

然后可以用get和set对对应对象的属性进行取值和赋值,
注意:如果该属性是私有的,不可操作这样会抛出异常IllegalAccessException,可以调用setAccessible(boolean flag)进行设置

4. 方法操作

对于Method对象,可以调用

invoke(Object obj, Object… args)方法进行调用其包装的方法。

Class cls = Class.forName("com.jsk.reflect_test.ReflectTestClass");
ReflectTestClass testClass = (ReflectTestClass) cls.newInstance();

Method method = cls.getDeclaredMethod("addition", int.class);
method.setAccessible(true);
int num = (int) method.invoke(testClass, 1234);
System.out.println(num);    
首先也应注意方法是否能对为外部开放,同时可以通过setAccessible设置
invoke方法,如果调用的是静态方法,obj可以为null,其余需类对应的对象
invoke会返回返回类型的包装类型,如int会返回Integer

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值