Java程序中的对象在运行时,会产生两种类型:编译时类型、运行时类型。
p
对象在编译时为Person,运行时Student,若是要获取运行时的对象可以使用反射。
反射获取对象的3种方法
- 使用用Class类的
的静态方法。forName(String clazzName)
必须是全类名(包名+类名)clazzName
Class<?> aClass = Class.forName(“reflect.TestClass”);
* 通过某个类的class属性获取该类的Class对象。(推荐使用)
```java
Class<TestClass> testClassClass = TestClass.class;
- 调用某个类的
方法getClass
TestClass testClass = new TestClass();
Class<?> clazz = testClass.getClass();
反射常用api
方法 | 说明 |
---|---|
Constructor<?> getConstuctor(Class<?>…paramType) | 根据形参获取指定的public构造器 |
Constructor<?> getConstuctor(Class<?>…paramType) | 根据形参获取指定的public构造器 |
Constructor<?>[] getConstructors() | 获取所有的public构造器 |
Constructor<?>[] getDeclaredConstructors() | 获取所有的构造器与权限无关 |
Constructor<?>[] Constructor getDeclaredConstructor(Class<?>… parameterTypes) () | 根据形参获取获取构造器(与权限无关) |
T newInstance() | 创建对象 |
测试:
@Test
public void testConstructor() throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
Class<TestClass> testClass = TestClass.class;
testClass.newInstance();//创建无参的构造器(无参的构造器可以直接创建)
Constructor<TestClass> constructor = testClass.getConstructor(String.class,String.class);
constructor.newInstance("张三","dsad");
Constructor<?>[] declaredConstructors = testClass.getDeclaredConstructors();
System.out.println("TestClass的构造器数量为:"+declaredConstructors.length);
//获取指定类型参数的构造器
Constructor<TestClass> declaredConstructor = testClass.getDeclaredConstructor(String.class,String.class);
//创建指定类型的构造器
TestClass testClass1 = declaredConstructor.newInstance("张三", "是一个好人");
}
获取方法
方法 | 说明 |
---|---|
Mehtod getMethod(String name,Class<?>…paramTypes) | 根据形参获取指定的public方法 |
Mehtod[] getMethods() | 根据形参获取所有的public方法 |
Method getDeclareMethod(String name,Class<?>…paramTypes) | 根据形参获取指定的方法(与权限无关) |
Method[] getDeclareMethods() | 根据形参获取所有的方法(与权限无关) |
@Test
public void testMethod() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
Class<TestClass> clazz = TestClass.class;
TestClass testClass = clazz.newInstance();
Method puInfo = clazz.getMethod("puInfo");
puInfo.invoke(testClass);
Method prInfo = clazz.getDeclaredMethod("prInfo");
prInfo.setAccessible(true);
prInfo.invoke(testClass);
//指定方法获取参数类型
Class<?>[] getMethodParams = clazz.getMethod("getMethodParam", String.class).getParameterTypes();
for (int i = 0; i < getMethodParams.length; i++) {
System.out.println(getMethodParams[i]);
}
System.out.println("------------所有的方法-------------------");
Method[] allMethod = clazz.getDeclaredMethods();
for (Method method:allMethod){
System.out.println(method);
}
System.out.println("----------------调用指定方法-------------------");
Class<Stu> stuClazz = Stu.class;
Stu stu = stuClazz.newInstance();
Method setMethod = stuClazz.getDeclaredMethod("setName", String.class);
setMethod.invoke(stu,"张三");
System.out.println(stu);
System.out.println("--------------调用私有方法-----------------");
Method privateMethod = stuClazz.getDeclaredMethod("privateMethod", String.class);
privateMethod.setAccessible(true);//设置可以访问私有权限
privateMethod.invoke(stu,"李四");
}
获取类包含的成员变量
方法 | 说明 |
---|---|
Field getField(String name) | 获取对应类的指定的名称public成员变量 |
Field getFields() | 获取对应类的指定的所有public成员变量 |
Field getDeclaredField(String name) | 获取对应类的指定的名称成员变量(与权限无关) |
Field[] getDeclaredFields() | 获取对应类的所有成员变量(与权限无关) |
@Test
public void getField() throws IllegalAccessException, InstantiationException {
Class<Stu> stuClazz = Stu.class;
Field[] declaredFields = stuClazz.getDeclaredFields();
System.out.println("---------------所有字段--------------------");
for (Field field:declaredFields) {
System.out.print("字段为:"+field+">>>>>,字段名称为:"+field.getName()+">>>>>,字段类型为:"+field.getType());
System.out.println();
}
}