代表类的成员变量(成员变量也称为类的属性)###简介
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
类的加载过程
//1.类的加载过程
//程序经过javaac.exe命令编译之后,会生成字节码文件(xxx.class)
//然后使用java.exe命令对某个字节码文件进行解释运行,相当于将某个字节码文件加载到内存中,此过程就称为类的加载,加载到内存终端类,称之为运行时类,作为一个Class的实例
//2.换句话说,Class的实例就对应着一个运行时类
//3.加载到内存中的运行时类,会缓存一定的时间,在此时间之内,我们可以通过不同的方式来获取此运行时类
与Java反射相关的类
类名 |
作用 |
Class类 |
代表类的实体,在运行的Java应用程序中表示类和接口 |
Field类 |
代表类的成员变量(成员变量也称为类的属性) |
Method类 |
代表类的方法 |
Constructor类 |
代表类的构造方法 |
Class类
Class代表类的实体,在运行的Java应用程序中表示类和接口。在这个类中提供了很多有用的方法,这里对他们简单的分类介绍。
方法 |
用途 |
asSubclass(Class<U> clazz) |
把传递的类的对象转换成代表其子类的对象 |
Cast |
把对象转换成代表类或是接口的对象 |
getClassLoader() |
获得类的加载器 |
getClasses() |
返回一个数组,数组中包含该类中所有公共类和接口类的对象 |
getDeclaredClasses() |
返回一个数组,数组中包含该类中所有类和接口类的对象 |
forName(String className) |
根据类名返回类的对象 |
getName() |
获得类的完整路径名字 |
newInstance() |
创建类的实例 |
getPackage() |
获得类的包 |
getSimpleName() |
获得类的名字 |
getSuperclass() |
获得当前类继承的父类的名字 |
getInterfaces() |
获得当前类实现的类或是接口 |
方法 |
用途 |
getField(String name) |
获得某个公有的属性对象 |
getFields() |
获得所有公有的属性对象 |
getDeclaredField(String name) |
获得某个属性对象 |
getDeclaredFields() |
获得所有属性对象 |
方法 |
用途 |
getAnnotation(Class<A> annotationClass) |
返回该类中与参数类型匹配的公有注解对象 |
getAnnotations() |
返回该类所有的公有注解对象 |
getDeclaredAnnotation(Class<A> annotationClass) |
返回该类中与参数类型匹配的所有注解对象 |
getDeclaredAnnotations() |
返回该类所有的注解对象 |
方法 |
用途 |
getConstructor(Class...<?> parameterTypes) |
获得该类中与参数类型匹配的公有构造方法 |
getConstructors() |
获得该类的所有公有构造方法 |
getDeclaredConstructor(Class...<?> parameterTypes) |
获得该类中与参数类型匹配的构造方法 |
getDeclaredConstructors() |
获得该类所有构造方法 |
方法 |
用途 |
getMethod(String name, Class...<?> parameterTypes) |
获得该类某个公有的方法 |
getMethods() |
获得该类所有公有的方法 |
getDeclaredMethod(String name, Class...<?> parameterTypes) |
获得该类某个方法 |
getDeclaredMethods() |
获得该类所有方法 |
方法 |
用途 |
isAnnotation() |
如果是注解类型则返回true |
isAnnotationPresent(Class<? extends Annotation> annotationClass) |
如果是指定类型注解类型则返回true |
isAnonymousClass() |
如果是匿名类则返回true |
isArray() |
如果是一个数组类则返回true |
isEnum() |
如果是枚举类则返回true |
isInstance(Object obj) |
如果obj是该类的实例则返回true |
isInterface() |
如果是接口类则返回true |
isLocalClass() |
如果是局部类则返回true |
isMemberClass() |
如果是内部类则返回true |
Field类
方法 |
用途 |
equals(Object obj) |
属性与obj相等则返回true |
get(Object obj) |
获得obj中对应的属性值 |
set(Object obj, Object value) |
设置obj中对应属性值 |
Method类
方法 |
用途 |
invoke(Object obj, Object... args) |
传递object对象及参数调用该对象对应的方法 |
Constructor类
方法 |
用途 |
newInstance(Object... initargs) |
根据传递的参数创建类的对象 |
获取运行时类的四种方式
@Test
public void test1() throws ClassNotFoundException {
//方式一:调用运行时类的属性
Class<Person> clazz1 = Person.class;
//方式二:通过运行时类的对象
Person person = new Person();
Class<? extends Person> clazz2 = person.getClass();
//方式三:调用Class的静态方法
Class<?> clazz3 = Class.forName("cn.yb.reflecttest.Person");
//方式四:使用类的加载器
ClassLoader classLoader = ReflectTest.class.getClassLoader();
Class<?> clazz4 = classLoader.loadClass("cn.yb.reflecttest.Person");
}
class Person{
private String name;
private int age;
public String test;
public String getTest() {
return test;
}
public void setTest(String test) {
this.test = test;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Person() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
使用newInstance()获取实例对象
@Test
public void test2() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class clazz = Class.forName("cn.yb.reflecttest.Person");
Person p = (Person) clazz.getDeclaredConstructor().newInstance();
Person person = (Person)clazz.newInstance();
System.out.println(p);
}
获取Field,Method,Constructor
@Test
public void test4() throws Exception{
Class clazz = Person.class;
Person p = (Person) clazz.newInstance();
Field test= clazz.getField("test");
System.out.println(test);
Method testMethod = clazz.getDeclaredMethod("testMethod",String.class);
testMethod.invoke(p,"test1");
Constructor constructor = clazz.getConstructor();
}
调用运行时类的指定属性,方法等
public void test5() throws Exception{
Class clazz = Person.class;
Person p = (Person) clazz.newInstance();
Field test = clazz.getField("test");
test.set(p,"new_test");
System.out.println(p);
//当调用private属性时, 需要使用name.setAccessible(true);
Field name = clazz.getField("name");
name.set(p,"new_name");
System.out.println(p);
}
当调用private属性或者方法时,需要使用setAccessible(true)
网友评论