1.获取Class对象的三种方式
1.通过class对象获取构造方法(先将一个类创建为一个class对象)
1.获取公开的构造方法(person.getconstructors)返回一个constructor类型的数组
2.获取所有的构造方法(person.declaredconstructors)
3.通过公开构造方法的参数获取对应的构造方法(person.getconstructor)
4.通过构造方法的参数可以获取任意的构造方法(person.getdeclaredconstructor)
1.1 类.class 获取
1.2 Class.forName 通过类的全限定名字来获取类所对应的CLass对象
1.3 通过对象来创建Class对象
为啥要获取字节码文件变成Class对象,因为获取字节码文件中的信息(构造方法, 属性,方法)
package com.qf.e_reflect;
public class Demo2 {
public static void main(String[] args) throws ClassNotFoundException {
//三种获取Class对象的方式:
//1.类.class 获取
Class<Person> personClass = Person.class;
System.out.println(personClass);
//2.Class.forName 通过类的全限定名字来获取类所对应的CLass对象
Class<?> aClass = Class.forName("com.qf.e_reflect.Person");
System.out.println(aClass);
//3. 通过对象来创建Class对象
Class<? extends Person> aClass1 = new Person().getClass();
System.out.println(aClass1);
//代码走到这一步 已经获取了Person.class字节码文件对象
//Person.class字节码文件 存了好多的类的信息 咋办,挨个取出来即可
}
}
2.获取Constructor对象
package com.qf.a_class;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Demo2 {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//1.获取person.class所对应的Class对象
Class<Person> personClass = Person.class;
//2.获取公开的构造方法
Constructor<?>[] constructors = personClass.getConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println(constructor);
}
System.out.println("===========");
//获取所有的构造方法
Constructor<?>[] declaredConstructors = personClass.getDeclaredConstructors();
for (Constructor<?> declaredConstructor : declaredConstructors) {
System.out.println(declaredConstructor);
}
System.out.println("===========");
//获取无参公开的构造方法
//getConstructor(Class<?>... parameterTypes)
//1.Class对象 Person.class String.class int.class
//... 可以多个 参数 中间使用,隔开即可
//
Constructor<Person> constructor = personClass.getConstructor(null);
System.out.println(constructor);
// Constructor<Person> constructor1 = personClass.getConstructor(String.class);
// System.out.println(constructor1);
//public Person (String name, int age, double weight) {
Constructor<Person> constructor1 = personClass.getConstructor(String.class, int.class, double.class);
System.out.println(constructor1);
System.out.println("===========");
Constructor<Person> declaredConstructor = personClass.getDeclaredConstructor();
System.out.println(declaredConstructor);
//private Person (String name) {
Constructor<Person> declaredConstructor1 = personClass.getDeclaredConstructor(String.class);
System.out.println(declaredConstructor1);
//构造方法有了,接下来咋办? 使用构造方法对象 创建实例对象
//借助于无参的构造出来一个对象
Person person = declaredConstructor.newInstance(null);
// newInstance(Object ... initargs) 对构造方法进行赋值的
Person person1 = constructor1.newInstance("goudan", 12, 98.7);
System.out.println(person1.name);
System.out.println(person1.age);
System.out.println(person1.weight);
}
}
3.获取Method对象
package com.qf.a_class;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Demo3 {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//1.获取Class对象
Class<Person> personClass = Person.class;
//2.通过class对象获取下面的方法对象
//获取所有的公开的方法和父类公开的方法
Method[] methods = personClass.getMethods();
for (Method method : methods) {
System.out.println(method);
}
System.out.println("=====");
//获取所有的方法
Method[] declaredMethods = personClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
}
System.out.println("===========");
//获取eat()
// Method getMethod(String name, Class<?>... parameterTypes)
Method eat = personClass.getMethod("eat", null);
System.out.println(eat);
//eat (String name, int age) {
Method eat1 = personClass.getMethod("eat", String.class, int.class);
System.out.println(eat1);
//获取私有化的方法
Method play = personClass.getDeclaredMethod("play", null);
System.out.println(play);
//获取之后呢? 方法对象获取之后 方法调用
//Object invoke(Object obj, Object... args)
//第一个参数 是 此方法在哪个对象下面
//第二个参数 是方法有可能有参数,传的是实参
Person person = personClass.getConstructor(null).newInstance(null);
eat.invoke(person, null);
eat1.invoke(person, "sb", 98);
//可以通过暴力反射 设置方法或者属性的权限问题
//can not access a member of class c
play.setAccessible(true);
play.invoke(person, null);
}
}
4.获取Field对象
package com.qf.a_class;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
public class Demo4 {
public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class<Person> personClass = Person.class;
//获取所有的公开的属性
Field[] fields = personClass.getFields();
for (Field field : fields) {
System.out.println(field);
}
System.out.println("=======");
//获取所有的属性对象
Field[] declaredFields = personClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
System.out.println("-------------");
//获取单个属性
Field name = personClass.getField("name");
System.out.println(name);
// Field age = personClass.getField("age");//这个报错不?
// System.out.println(age);
Field age = personClass.getDeclaredField("age");
System.out.println(age);
//属性获取完以后? 赋值
Person person = personClass.getConstructor(null).newInstance(null);
name.set(person, "狗蛋");//将狗蛋赋值给person 对象下面的 name属性
System.out.println(name.get(person));//在指定的对象下面获取 name属性值
// can not access a member
age.setAccessible(true);
age.set(person, 67);
System.out.println(age.get(person));
}
}