1、什么是反射
在运行期间
- 对于类:能够知道这个类的所有属性及方法
- 对于对象:能够修改这个对象的所有属性、调用所有方法、所属类的所有属性及方法
2、Class对象的获取
2.1、类名.Class
JVM会装载Dog类的Class对象到内存,不会初始化Dog类
Class<Dog> dogClass = Dog.class;
打印
//什么都不会打印的
2.2、 Class.forName()
JVM会装载Dog类的Class对象到内存,初始化Dog类,执行Dog类的静态代码块
Class<?> dog = Class.forName("other.Dog");
输出:
Dog 的静态代码块执行
2.3、getClass()
getClass()方法的方法是在通过的类的实例调用的,即已经创建了类的实例。
Dog dog = new Dog("旺财",0,100,"拉布拉多");
Class<? extends Dog> aClass = dog.getClass();
输出:
Dog 的静态代码块执行
Dog 的非静态代码块执行
other.Dog 的构造方法执行
3、创建实例
- newInstance()方法, 为类创建一个新实例,调用默认构造器
Class<Dog> dogClass = Dog.class;
Dog dog = dogClass.newInstance();
dog.eat("狗粮");
// 输出:Dog 的静态代码块执行
// 输出:Dog 的非静态代码块执行
// 输出:Dog 的无参构造方法执行
// 输出:Dog 吃了--狗粮
- 使用指定构造器,getConstructor(),创建对象
//获取Dog所对应的Class对象
Class<Dog> dogClass = Dog.class;
//获取Dog类,参数类型为String,int,int,Sting的构造器
Constructor<Dog> constructor = dogClass
.getConstructor(String.class, int.class, int.class, String.class);
//根据构造器创建实例
Dog dog = constructor.newInstance("旺财", 0, 100, "拉布拉多");
dog.eat("狗粮");
// 输出:Dog 的静态代码块执行
// 输出:Dog 的非静态代码块执行
// 输出:Dog 的4参数构造方法执行
// 输出:Dog 吃了--狗粮
4、获取属性 Field
- getFiled:访问公有(Public)的成员变量
- getDeclaredField:所有已声明的成员变量,但不能得到其父类的成员变量
Dog dog = new Dog("旺财", 10, 100, "拉布拉多");
//获取Dog所对应的Class对象
Class<Dog> dogClass = (Class<Dog>) dog.getClass();
//获取全部属性
Field[] declaredFields = dogClass.getDeclaredFields();
//获取名为name的属性
Field nameField = dogClass.getDeclaredField("name");
//获取属性名称
String name = nameField.getName();//输出:name
//获取属性修饰符 PUBLIC: 1 PRIVATE: 2 STATIC: 8 然后相加PUBLIC+STATIC输出9
int modifiers = nameField.getModifiers();//输出:2
//获取属性类型
Class<?> type = nameField.getType();//输出:class java.lang.String
// 设置操作权限为true
nameField.setAccessible(true);
//获取指定属性的值
nameField.get(dog);//输出:旺财
//修改值
nameField.set(dog,"小白");//输出:小白
//获取sex属性
Field sexField = dogClass.getDeclaredField("sex");
// 设置操作权限为true
sexField.setAccessible(true);
//获取指定int属性的值
sexField.getInt(dog);//输出:10
//修改int值
sexField.setInt(dog, 11);//输出:11
5、调用方法
Dog dog = new Dog("旺财", 10, 100, "拉布拉多");
//获取Dog所对应的Class对象
Class<? extends Dog> dogClass = dog.getClass();
Method[] methods = dogClass.getMethods();
//获取dog的eat()方法
Method method = dogClass.getMethod("eat", String.class);//输出:public void other.Dog.eat(java.lang.String)
//调用dog的eat()方法
method.invoke(dog,"狗粮");//输出:Dog 吃了--狗粮
//获取私有方法say()
Method sayMethod = dogClass.getDeclaredMethod("say", String.class);
//设置方法控制权限
sayMethod.setAccessible(true);
//调用say()方法
sayMethod.invoke(dog,"汪汪");//输出:Dog 说了--汪汪
3、常用方法
- getName()
获取类名(含包名)
Class<Dog> dogClass = Dog.class;
String name = dogClass.getName();
System.out.println("输出:"+name);
// 输出:other.Dog
- getClassLoader()
返回该类的类加载器。
Class<Dog> dogClass = Dog.class;
ClassLoader classLoader = dogClass.getClassLoader();
- getSuperclass()
返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的Class。
Class<Dog> dogClass = Dog.class;
Class<? super Dog> superclass = dogClass.getSuperclass();
System.out.println("输出:" +superclass);
// 输出:class java.lang.Object
Dog类
package other;
public class Dog {
static {
System.out.println("输出:" + "Dog 的静态代码块执行");
}
{
System.out.println("输出:" + "Dog 的非静态代码块执行");
}
/////////////// 全是私有化的属性////////////////////
private String name;
private int sex;
private int weight;
private String type;
public Dog() {
System.out.println("输出:" + "Dog 的无参构造方法执行");
}
public Dog(String name, int sex, int weight, String type) {
System.out.println("输出:" + "Dog 的4参数构造方法执行");
this.name = name;
this.sex = sex;
this.weight = weight;
this.type = type;
}
public void eat(String food) {
System.out.println("输出:" + "Dog 吃了--" + food);
}
private void say(String word) {
System.out.println("输出:" + "Dog 说了--" + word);
}
/////////////// 只提供了get方法////////////////////
public String getName() {
System.out.println("输出:" + "Dog的getName方法执行");
return name;
}
public int getSex() {
System.out.println("输出:" + "Dog的getSex方法执行");
return sex;
}
public int getWeight() {
System.out.println("输出:" + "Dog的getWeight方法执行");
return weight;
}
public String getType() {
System.out.println("输出:" + "Dog的getType方法执行");
return type;
}
}