基本概念
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、getterfield field = cls.getfield("num");
field.set(demo, 1000);int filedvalue = (integer) field.get(demo);// 2.1 非公共方法的 setter、getterfield privatefield = cls.getdeclaredfield("str");
privatefield.setaccessible(true); // 关键 -> 操作之前,需要设置访问权限privatefield.set(demo, "hello");
string privatefieldvalue = (string) privatefield.get(demo);
method1.获取方法对象获取所有方法
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 ,容量为 3int [ ] 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 ,值为 100array.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));
以上就是08.java 基础 - 反射的内容。
