反射基础:
文章目录结构
1、获取Class实例的常用方式
2、获取field属性的方式
(1)获取运行时类及其父类中声明为public的的属性
(2)获取运行时类本身的所有声明的属性
·获取类的属性类型及其属性名称
(3)获取指定属性,并且对指定的属性进行相应的赋值(包含public、private、protected)
3、获取method方法的方式
(1)获取运行时类及其父类中声明为public的的方法
(2)获取运行时类本身的所有声明的方法
·获取方法中的权限修饰符、返回值类型、方法名、形参列表
(3)获取指定方法,并且对指定的方法进行相应的赋值并运行(包含public、private、protected)
4、获取类的构造器
(1)获取类的所有构造器
(2)获取类的指定构造器
1、三种常用方式和使用类加载器获取获取Class类实例
/*
* java.lang.Class:是反射的源头。
* 我们创建了一个类,通过编译生成对应的.class文件,之后我们加载(JVM的类加载器)此.class文件。
* 此.class文件加载到内存以后就是一个运行时类(存放在缓存区)。那么这个运行时类本身就是一个大的Class实例。
* 1、每一个运行时类只加载一次。
* 2、有了Class类的实例以后:(1)可以创建对应的运行类的对象(2)可以获取对应的运行时类的完整结构(属性、方法、构造器、父类、所在的包、异常、注解、内部类)
* (3)调用对应的运行时类指定的结构(属性、方法、构造器)
* (4)动态代理:反射的应用
*/
@Test
public void test1() throws ClassNotFoundException{
//获取运行时类的class属性
Class<Person> clazz1 = Person.class;
System.out.println(clazz1.getName());
//通过运行时类的对象获取
Person person = new Person();
Class<Person> clazz2 = (Class<Person>) person.getClass();
System.out.println(clazz2.getName());
//通过Class类的静态方法:forName()
Class clazz3 = Class.forName("cn.zyy.testReflect.Person");
System.out.println(clazz3.getName());
//通过类的加载器
ClassLoader classLoader = this.getClass().getClassLoader();
Class clazz4 = classLoader.loadClass("cn.zyy.testReflect.Person");
System.out.println(clazz4.getName());
}
2、获取field属性的方式
@Test
public void test2() throws NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException{
//1、获取运行时类及其父类中声明为public的的属性
Class clazz = Person.class;
Field[] fields_public = clazz.getFields();
for(Field field : fields_public){
System.out.println(field.getName());
}
//2、获取运行时类本身的所有声明的属性
Field[] fields_own = clazz.getDeclaredFields();
System.out.println("获取运行时类本身的所有声明的属性==开始");
for(Field field : fields_own){
//获取类的属性类型、属性名称、权限修饰符
int ii = field.getModifiers();
String modifier = Modifier.toString(ii);
System.out.println("类的"+field.getName()+"属性的权限修饰符是:"+modifier);
Class fieldTypeClass = field.getType();
String fieldType = fieldTypeClass.getName();
System.out.println("类的"+field.getName()+"属性的类型是:"+fieldType);
}
System.out.println("获取运行时类本身的所有声明的属性==结束");
//3、获取指定属性,并且对指定的属性进行相应的赋值(包含public、private、protected)
Object obj = clazz.newInstance();
Person person = (Person) obj;
//private属性
Field field_name = clazz.getDeclaredField("name");
field_name.setAccessible(true);
field_name.set(person, "张哈哈");
System.out.println(field_name.get(person));
//public属性
Field field_address = clazz.getDeclaredField("address");
field_address.set(person, "beijing");
System.out.println(field_address.get(person));
//protected属性
Field field_id = clazz.getDeclaredField("id");
field_id.set(person, 12);
System.out.println(field_id.get(person));
}
3、获取method方法的方式
@Test
public void test3() throws Exception{
//1、获取运行时类及其父类中声明为public的的方法
Class clazz = Person.class;
Method[] methods_public = clazz.getMethods();
for(Method method : methods_public){
System.out.println(method.getName());
}
//2、获取运行时类本身的所有声明的方法
Method[] methods_own = clazz.getDeclaredMethods();
for(Method method : methods_own){
//获取方法中的权限修饰符、返回值类型、方法名、形参列表
int ii = method.getModifiers();
String modifier = Modifier.toString(ii);
System.out.println("类的"+method.getName()+"方法的权限修饰符是:"+modifier);
Class<?> returnTypeClass = method.getReturnType();
String returnType = returnTypeClass.getName();
System.out.println("类的"+method.getName()+"方法的返回值类型是:"+returnType);
Class [] parameters = method.getParameterTypes();
}
//3、获取指定方法,并且对指定的方法进行相应的赋值并运行(包含public、private、protected)
Person person = (Person) clazz.newInstance();
//private方法(注意要使用getDeclaredMethod,如果使用getMethod,那么会出现找不到method的情况)
Method method_getNameById = clazz.getDeclaredMethod("getNameById", Integer.class);
method_getNameById.setAccessible(true);
method_getNameById.invoke(person, 12);
//public
Method method_getInfo = clazz.getDeclaredMethod("getInfo", String.class);
Object returnValue = method_getInfo.invoke(person, "haha");
System.out.println(returnValue);
}
4、获取类的构造器
@Test
public void test4() throws Exception{
Class clazz = Person.class;
//1、获取类的所有构造器
Constructor [] constructors_public = clazz.getConstructors();
System.out.println("获取所有public Constructor 开始");
for(Constructor constructor : constructors_public){
System.out.println(constructor.getName());
}
System.out.println("获取所有public Constructor 结束");
Constructor [] constructors_own = clazz.getDeclaredConstructors();
System.out.println("获取所有own Constructor 开始");
for(Constructor constructor : constructors_own){
System.out.println(constructor.getName());
}
System.out.println("获取所有own Constructor 结束");
//2、获取类的指定构造器
Constructor constructor = clazz.getConstructor(String.class,int.class,String.class);
Person person = (Person) constructor.newInstance("zhangyy",12,"zhongguo");
System.out.println(person.getAddress());
}
例子中使用的示例类Person类:
public class Person {
private String name;
protected int id;
public String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getInfo(String name){
if("haha".equals(name)){
return 1;
}else {
return 0;
}
}
@SuppressWarnings("unused")
private void getNameById(Integer id){
System.out.println(id);
}
@Override
public String toString() {
return "Person [name=" + name + ", id=" + id + ", address=" + address
+ "]";
}
public Person(String name, int id, String address) {
super();
this.name = name;
this.id = id;
this.address = address;
}
public Person() {
super();
}
}