您的位置:首页 > 编程语言 > Java开发

08.Java 基础 - 反射

2016-07-12 21:00 393 查看

基本概念

Java 反射机制可以让我们在编译期(Compile Time)之外的运行期(Runtime)检查类,接口,变量以及方法的信息。

反射的作用如下:

对于任意一个类,都能够知道这个类的所有属性和方法;

对于任意一个对象,都能够调用它的任意一个方法和属性。

Class

想要获取一个类的信息,首先需要获取类的 Class 对象。

Java中的所有类型包括基本类型(int、long、float 等),即使是数组都有与之关联的 Class 对象。

取得类的对象

//1.在编译期获取类对象
Class cls = Demo.class

//2.在运行期获取类对象(注意:需要包括完整的包名)
Cllss clas = Class.forName("com.test.Demo")


取得类的名称

Class cls = ...

// 1.获取完整类型(包括包名)
String className = cls.getName();

// 2.获取简单类名
String simpleClassName =cls.getSimpleName();


取得类的修饰符

Class cls = ...

// 修饰符都被包装成一个 int 类型的数字,这样每个修饰符都是一个位标识(flag bit)
int modifiers  = cls.getModifiers();

// 判断修饰符类型
Modifier.isPublic( modifiers);
Modifier.isProtected( modifiers);
Modifier.isPrivate( modifiers);
Modifier.isAbstract( modifiers);
Modifier.isInterface( modifiers);
Modifier.isFinal( modifiers);
Modifier.isStatic( modifiers);
Modifier.isNative( modifiers);
Modifier.isStrict( modifiers);
Modifier.isSynchronized( modifiers);
Modifier.isTransient( modifiers);
Modifier.isVolatile( modifiers);


取得类所在的包信息

Class cls =...
Package p = cls.getPackage();


取得类继承的父类

Class cls = ...
Class superClass  = cls.getSuperclass();


取得类实现的接口类型

Class cls = ...

// 类可以实现多个接口,因此返回的是接口数组
Class [ ] interfaces = cls.getInterfaces();


Constructor

在 Java 中 ,Constructor 类用表示一个构造器对象。

获取公共构造方法

Class cls = ...

// 1.获取所有构造函数
Constructor[] constructors = cls.getConstructors();

// 2.获取指定构造函数,不存在匹配则抛出异常。
// 对应的构造函数入参类为 Person(String str, int i)
Constructor constructor =
cls.getConstructor(new Class[]{String.class,int.class});


获取构造函数的入参类型

Constructor constructor = ...

// 因为构造函数的入参有多个,因此返回的数组
Class [] paramterTypes = constructor.getParameterTypes();
for(Class paramterType: paramterTypes ){
// do something...
}


构造函数实例化类

Class cls = ...
Constructor constructor = cls.getConstructor(new Class[]{String.class});

// Object[] 数组表示入参的具体值,需要与 Class[] 的入参类型完全匹配
Demo demo = (Demo) constructor.newInstance(new Object[]{"hello"});


Field

在 Java 中 ,Field类用表示一个变量对象。

获取所有变量(公共,非公共)

Class cls = ...

// 1.获取所有公共变量
Field[] fields = cls.getFields();

// 2.获取所有非公共变量
Field [] privateFields =cls.getDeclaredFields();


获取指定变量(公共,非公共)

Class cls = ...

//入参为变量名称,名称不匹配则抛出异常

// 获取指定公共变量
Field field = cls.getField("num");
// 获取指定非公共变量
Field privateField = cls.getDeclaredField("str");


操作变量

Class<?> cls = Demo.class;
Demo demo = (Demo) cls.newInstance();

// 1.1.公共方法的 setter、getter
Field field = cls.getField("num");
field.set(demo, 1000);
int filedValue  = (Integer) field.get(demo);

// 2.1 非公共方法的 setter、getter
Field privateField = cls.getDeclaredField("str");
privateField.setAccessible(true); // 关键 -> 操作之前,需要设置访问权限
privateField.set(demo, "hello");
String privateFieldValue = (String) privateField.get(demo);


Method

1.获取方法对象

获取所有方法

Class cls = ...

// 1.获取所有公共方法(包括从父类继承而来的)
Method[] methods = cls.getMethods();

// 2.获取所有非公共方法(包括从父类继承而来的)
Method [] privateMethods = cls.getDeclaredMethods();


获取指定方法

Class cls = ...

// 1.获取指定公共方法,入参为:方法名、方法入参
Method method = cls.getMethod("print", new Class[]{String.class});

// 2.获取指定非公共方法,入参为:方法名、方法入参
Method privateMethod = cls.getDeclaredMethod("say", new Class[]{int.class});


获取方法的参数类型

Method method = ...

// 1.获取方法的所有入参类型
Class [] paramterTypes = method.getParameterTypes();

// 2.获取方法的返回值类型
Class reeturnType = method.getReturnType();


执行方法

Class cls = Demo.class;
Demo demo = (Demo) cls.newInstance();
Method method = cls.getMethod("print", new Class[]{String.class});

//1.执行公用方法,入参为:类实例,方法入参的具体值
method.invoke(demo, "hello");

//2.执行非公共方法
Method privateMethod =
cls.getDeclaredMethod("print", new Class[]{String.class});
privateMethod.setAccessible(true); // 关键 -> 操作之前,需要获得访问权限
privateMethod.invoke(demo, "hello");


判断 getter/setter 方法

public static boolean isGetter(Method method){
if(!method.getName().startsWith("get")){
return false;
}
if(method.getParameterTypes().length !=0){
return false;
}
if(void.class.equals(method.getReturnType())){
return false;
}
return true;
}

public static boolean isSetter(Method method){
if(!method.getName().startsWith("set")){
return false;
}
if(method.getParameterTypes().length !=1){
return false;
}
return true;
}


Array

在 Java 中,用 Array 类表示数组对象。

获取数组对象

int [ ] intArray = ...
Class arrayCls = intArray.class;


获取数组成员类型

Class arrayCls = ...
Class arrayComponentType =arrayCls .getComponentType();


创建数组

// 创建一个数组,类型为 int ,容量为 3
int [ ] intArray = (int[]) Array.newInstance(int.class, 3);

//在 JVM 中字母I代表int类型,左边的‘[’代表我想要的是一个int类型的数组
Class intArrayClass = Class.forName("[I");

//注意‘[L’的右边是类名,类名的右边是一个‘;’符号。这个的含义是一个指定类型的数组。
stringArrayClass = Class.forName("[Ljava.lang.String;");


添加数组元素

int [ ] intArray = ...

// 添加元素,数组为 intArray,位置为 0 ,值为 100
Array.set(intArray, 0, 100);
Array.set(intArray, 1, 200);
System.out.println("intArray[0] = " + Array.get(intArray, 0));
System.out.println("intArray[1] = " + Array.get(intArray, 1));
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Java Reflect 反射