Java学习-12-韩顺平老师
Java-反射机制02
目录:
01-通过反射获取类的结构信息
02-通过反射创建对象
03-通过反射访问类的成员
01-通过反射获取类的结构信息
java.lang.Class:
1.getName:获取全类名
2.getSimpleName:获取简单类名
3.getFields:获取所有public修饰的属性,包含本类以及父类的
4.getDeclaredFields:获取本类中所有属性
5.getMethods:获取所有public修饰的方法,包含本类以及父类的
6.getDeclaredMethods:获取本类中所有方法
7.getConstructors:获取所有public修饰的构造器,包含本类以及父类的
8.getDeclaredConstructors;获取本类中所有构造器
9.getPackage:以Package形式返回 包信息
10.getSuperClass:以Class形式返回父类信息
11.getlnterfaces:l以Classl1形式返回接口信息
12.getAnnotations:以Annotationl 形式返回注解信息
public class Class_ {
public static void main(String[] args) throws ClassNotFoundException {
Class<?> cls = Class.forName("com.zcc.class_.Animal");
// getName
System.out.println(cls.getName()); // com.zcc.class_.Animal
// getSimpleName
System.out.println(cls.getSimpleName()); // Animal
// getFields 输出如下
// public int com.zcc.class_.Animal.num1
// public int com.zcc.class_.A.i1
Field[] fields = cls.getFields();
for (Field field : fields) {
System.out.println(field);
}
// getDeclaredFields 输出以下
/*
public int com.zcc.class_.Animal.num1
1
int
num1
protected int com.zcc.class_.Animal.num2
4
int
num2
int com.zcc.class_.Animal.num3
0
int
num3
private int com.zcc.class_.Animal.num4
2
int
num4
*/
Field[] declaredFields = cls.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
System.out.println(declaredField.getModifiers());
System.out.println(declaredField.getType());
System.out.println(declaredField.getName());
}
// 以下两个与上述两个一致
// cls.getMethods() / cls.getDeclaredMethods()
// cls.getConstructors() / cls.getDeclaredConstructors()
// getPackage
System.out.println(cls.getPackage()); // package com.zcc.class_
// getInterfaces
System.out.println(cls.getInterfaces().length); // 1
// getAnnotations
System.out.println(cls.getAnnotations().length); // 1
}
}
class A{
public int i1 =10;
public void s1(){}
}
interface IA{}
@Deprecated
class Animal extends A implements IA{
public int num1 = 10;
protected int num2 =20;
int num3 =30;
private int num4 =40;
public Animal(){
}
public Animal(int num1){
num1 =num1;
}
public void m1(){}
protected void m2(){}
void m3(){}
private void m4(){}
}
java.lang.reflect.Constructor:
1.getModifiers:以int形式返回修饰符
2.getName:返回构造器名(全类名)
3.getParameterTypes:以Class[]返回参数类型数组
演示代码写在上面
java.lang.reflect.Field:
1.getModifiers:以int形式返回修饰符
[说明:默认修饰符 是0,public #1, private # 2, protected # 4,
static是8,final是 16]
2.getType:lClass形式返回类型
3.getName:返回属性名
演示代码写在上面
java.lang.reflect.Method:
1.getModifiers:l以int形式返回修饰符
[说明:默认修饰符 是0,
public #1, private # 2, protected # 4,
static是8,final是 16]
2.getReturnType:lClass形式获取 返回类型
3.getName:返回方法名
4.getParameterTypes:l以Class1返回参数类型数组
演示代码写在上方
02-通过反射创建对象
1.方式一:调用类中的public修饰的无参构造器
2.方式二:调用类中的指定构造器
3.Class类相关方法
newlnstance:调用类中的无参构造器,获取对应类的对象
getConstructor(Class…clazz):根据参数列表,获取对应的public构造器对象
getDecalaredConstructor(ClasS…clazz):根据参数列表,获取对应的所有构造器
对象,主要用来获取私有的,里面填入对应的参数Class对象,会自动匹配构造器。
4.Constructor类相关方法
setAccessible:爆破
newlnstance(Object…obj):调用构造器
public class CreateObjectByClass {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
// Class
Class<?> cls = Class.forName("com.zcc.class_.Person");
// 通过newInstance获得 实例对象
Person p = (Person)cls.newInstance();
// 使用构造器
Constructor<?> constructor = cls.getConstructor();
Person p1 =(Person) constructor.newInstance();
// 使用有参构造器, 在后面填入参数列表对应的Class对象,会自动匹配构造器
Constructor<?> declaredConstructor = cls.getDeclaredConstructor(String.class, int.class);
// 因为是私有的构造器,所以采取爆破的方式访问
declaredConstructor.setAccessible(true);
Person p2 = (Person)declaredConstructor.newInstance("张三", 19);
System.out.println(p);
System.out.println(p1);
System.out.println(p2);
/* 输出
Person{name='王五', age=13}
Person{name='王五', age=13}
Person{name='张三', age=19}
*/
}
}
class Person{
private String name ="王五";
private int age = 13;
// 默认构造器
public Person(){}
// 私有有参构造器
private Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
03-通过反射访问类的成员
访问属性:
1.根据方法名和参数列表获取Method方法对象:Method m =
clazz.getDeclaredMethod(方法名,xx.class);//得到本类的所有方法
2.获取对象:Object o=clazz.newlnstance();
3.暴破:m.setAccessible(true);
4.访问:Object returnValue=m.invoke (0,实参列表);
5.注意:如果是静态方法,则invoke的参数。,可以写成null!
访问方法:
1.根据属性名获取Field对象
Field f=clazz对象.getDeclaredField(属性名);
2.暴破:f.setAccessible(true);1/f是Field
3.访问
f.set(o,值);
syso(f.get(o));
4.如果是静态属性,则set和get中的参数o,可以写成null
代码演示:
public class Visit {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Class<?> cls = Class.forName("com.zcc.class_.Person");
Object o = cls.newInstance();
// getField获取的共有属性
Field field = cls.getField("age");
// 访问共有属性
System.out.println(field.get(o)); // 18
System.out.println(field.get(null)); // 18
// 获取私有属性
Field name = cls.getDeclaredField("name");
// 访问私有属性必须使用setAccessible爆破
name.setAccessible(true);
System.out.println(name.get(o));// 张三
// 获取公开方法
Method getAge = cls.getMethod("getAge");
System.out.println(getAge.invoke(o)); // 18
System.out.println(getAge.invoke(null)); // 18
// 获取私有方法
Method declaredMethod = cls.getDeclaredMethod("getName");
// 私有方法必须爆破才能访问
declaredMethod.setAccessible(true);
System.out.println(declaredMethod.invoke(o));
}
}
class Person{
// 私有属性
private String name = "张三";
// 公开静态属性
public static int age = 18;
// 共有方法
public static int getAge(){
return age;
}
// 私有方法
private String getName(){
return this.name;
}
}
反射机制小结,欢迎大家交流学习!