1 获取Class(字节码)对象的方式
Class.foName("全类名");
类名.class
对象.getClass():getClass方法在Oject中定义着
编写Person类 Person.java
public class Person {
private String name;
private int age;
public String a;
protected String b;
String c;
private String d;
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public void eat() {
System.out.println("eat...");
}
public void eat(String food) {
System.out.println("eat..." + food);
}
}
编写获取字节码测试类ReflectDemo1.java
public class ReflectDemo1 {
public static void main(String[] args) throws Exception {
// 1.Class.foName("")
Class<?> clazz = Class.forName("com.tang.reflect.domain.Person");
System.out.println(clazz);
// 2类名.class
Class<?> clazz1 = Person.class;
System.out.println(clazz1);
// 3对象.getClass()
Person person = new Person();
Class<? extends Person> clazz2 = person.getClass();
System.out.println(clazz2);
System.out.println(clazz==clazz1);
System.out.println(clazz==clazz2);
System.out.println(clazz2==clazz1);
Class<?> clazz3 = Student.class;
System.out.println(clazz3 == clazz);
}
}
运行结果
结论:同一字节码文件在一次运行过程中,只会被加载一次,不论通过哪一种方式获得的Class对象都是同一个
2 Class对象功能
获取功能
2.1获取成员变量们
Field getField(String name);//获取单个的public修饰的变量
Field[] getFields();//获取所有public修饰的变量
Field getDeclaredField(String name);//获取任意的变量
Field[] getDeclaredFields();//获取所有的变量,无关修饰符
setAccessible(true);//忽略访问权限修饰符的安全检查,暴力反射
Filed成员变量
set(Object obj, Object value);//(1)设置值
Object get(Object obj);(2)获取值
代码示例:
public void getFields() throws Exception {
Class<?> clazz = Class.forName("com.tang.reflect.domain.Person");
// 获取所有的成员变量
System.out.println("-----------------getFields");
Field[] fields = clazz.getFields();
Arrays.asList(fields).stream().forEach(System.out::println);
System.out.println("-----------------getField");
Field a = clazz.getField("a");
System.out.println(a);
// 获取成员变量a的值
Person p = new Person();
Object value = a.get(p);
System.out.println(value);
// 设置a的值
a.set(p, "xxx");
System.out.println(p);
System.out.println("-----------------getDeclaredFields");
Field[] fields2 = clazz.getDeclaredFields();
Arrays.asList(fields2).stream().forEach(System.out::println);
System.out.println("-----------------getDeclaredField");
Field d = clazz.getDeclaredField("d");
// 忽略访问权限修饰符的安全检查
d.setAccessible(true);// 暴力反射
System.out.println(d.get(p));
System.out.println("-----------------");
}
2.2获取构造方法
Constructor<T> getConstructor(Class<?>... parameterTypes);
Constructor<?>[] getConstructors();
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes);
Constructor<?>[] getDeclaredConstructors();
Constructor构造
T newInstance(Object... initargs);//创建对象
Class.newInstance();//;直接创建空参对象
代码示例:
public void getConstructors() throws Exception {
Class<?> clazz = Class.forName("com.tang.reflect.domain.Person");
// Constructor<T> getConstructor(Class<?>... parameterTypes);
System.out.println("----------getConstructor有参");
Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
System.out.println(constructor);
// 创建对象
Object person = constructor.newInstance("张三", 24);
System.out.println(person);
System.out.println("----------getConstructor空参");
Constructor<?> constructor2 = clazz.getConstructor();
Object person2 = constructor2.newInstance();
System.out.println(person2);
// 如果使用空参,那么操作是可以简化的
Object person3 = clazz.newInstance();//
System.out.println(person3);
}
2.3 获取成员方法
Method getMethod(String name, Class<?>... parameterTypes);
Method[] getMethods();
Method getDeclaredMethod(String name, Class<?>... parameterTypes);
Method[] getDeclaredMethods();
Method 方法
Object invoke(Object obj, Object... args);//执行方法
String getName();//获得方法名
代码示例:
public void getMethods() throws Exception {
Class<?> clazz = Class.forName("com.tang.reflect.domain.Person");
// 获得指定名称的方法
System.out.println("-------------------getMethod");
Method method = clazz.getMethod("eat");
Object person = clazz.newInstance();
Object invoke = method.invoke(person);
System.out.println(invoke);
Method method1 = clazz.getMethod("eat", String.class);
Object invoke1 = method1.invoke(person, "饭");
System.out.println(invoke1);
// 获取所有public修饰的方法
System.out.println("-------------------getMethods");
Method[] methods = clazz.getMethods();
Arrays.asList(methods).stream().forEach(e -> {
e.setAccessible(true);//暴力反射
System.out.println(e);
System.out.println(e.getName());
});
}
2.4 获取类名
String getName();
代码示例
public void getClazz() throws Exception {
//获取类名
String clazzName = clazz.getName();
System.out.println(clazzName);
}