JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
简单来说就是运行时能够获得并使用类的信息的方法叫做反射。
众所周知Java有个Object 类,是所有Java 类的继承根源,其内声明了数个应该在所有Java 类中被改写的方法:hashCode()、equals()、clone()、toString()、getClass()等。其中getClass()返回一个Class 对象。
Class 类十分特殊。它和一般类一样继承自Object,其实体用以表达Java程序运行时的classes和interfaces,也用来表达enum、array、primitive Java types(boolean, byte, char, short, int, long, float, double)以及关键词void。当一个class被加载,或当加载器(class loader)的defineClass()被JVM调用,JVM 便自动产生一个Class 对象
package com.reflect;
public class Animal {
public String name;
public static void main(String[] args) throws ClassNotFoundException {
Animal animal = new Dog();
System.out.println("小名家里有一只" + animal.name);
//方法一,通过对象获得
Class> class1 = animal.getClass();
//方法二,通过字符串获得(包名+类名,可动态创建对象)
Class> class2 = Class.forName("com.reflect.Animal");
//方法三,通过类的静态成员class获得
Class> class3 = Cat.class;
//方法四,获得父类型
Class> class4 = class3.getSuperclass();
//方法五,只能获得基本数据类型
Class> class5 = Double.TYPE;
System.out.println("class1类名:"+class1.getName());
System.out.println("class2类名:"+class2.getName());
System.out.println("class3类名:"+class3.getName());
System.out.println("class4类名:"+class4.getName());
System.out.println("class5类名:"+class5.getName());
}
}
class Dog extends Animal {
public Dog() {
this.name = "狗狗";
}
}
class Cat extends Animal {
public Cat() {
this.name = "猫咪";
}
}
结果
组成部分 | 访问方法 | 返回值类型 | 说明 |
包路径 | getPackage() | Package对象 | 获得该类的存放路径 |
类名称 | getName() | String对象 | 获得该类的名称 |
继承类 | getSuperclass() | Class对象 | 获得该类继承的类 |
实现接口 | getInterfaces() | Class型数组 | 获得该类实现的所有接口 |
构造方法 | getConstructor() | Constructor型数组 | 获得所有权限为public的构造方法 |
getConstructor(Class>…parameterTypes) | Constructor对象 | 获得权限为public的指定构造方法 | |
getDeclaredConstructors() | Constructor型数组 | 获得所有构造方法,按声明顺序返回 | |
getDeclaredConstructor(Class>…parameterTypes) | Constructor对象 | 获得指定构造方法 | |
方法 | getMethods() | Method型数组 | 获得所有权限为public的方法 |
getMethod(String name, Class>…parameterTypes) | Method对象 | 获得权限为public的方法 | |
getDeclaredMethods() | Method型数组 | 获得所有方法,按声明顺序返回 | |
getDeclaredMethods(String name, Class>…parameterTypes) | Method对象 | 获得指定方法 | |
成员变量 | getFields() | Field型数组 | 获得所有权限为public的成员变量 |
getField(String name) | Field对象 | 获得权限为public的指定成员变量 | |
getDeclaredFields() | Field型数组 | 获得所有成员变量,按声明顺序返回 | |
getDeclaredFields(String name) | Field对象 | 获得指定成员变量 | |
内部类 | getClasses() | Class型数组 | 获得所有权限为public的内部类 |
getDeclaredClasses() | Class型数组 | 获得所有内部类 | |
内部类的声明类 | getDeclaringClass() | Class对象 | 如果该类为内部类,则返回它的成员类,否则返回null |
在通过getFields()和getMethods()方法依次获得权限为public的成员变量和方法时,将包含从超类中继承到的成员变量和方法;而通过方法getDeclaredFiedls()和getDeclareMethods()只是获得在本类中定义的所有成员变量和方法。
这里我准备好了一个实体类,接下来的所有的测试都将根据这个实体类来实现
package com.reflect;
public class Fruit {
String name;
String color;
String price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public Fruit(String name, String color, String price) {
this.name = name;
this.color = color;
this.price = price;
}
public Fruit(String name, String color) {
this.name = name;
this.color = color;
}
public Fruit() {
}
public void getInfo(){
System.out.println(this.color+"的"+this.name+",价钱是"+this.price+"元/斤");
}
public void outInfo(String name,int price){
System.out.println("这种水果的名字是"+name+",价钱是"+price+"元/斤");
}
public void outNull(){
System.out.println("就是想输出一下。。。");
}
@Override
public String toString() {
return "Fruit{" +
"name='" + name + '\'' +
", color='" + color + '\'' +
", price='" + price + '\'' +
'}';
}
}
//通过反射实例化一个实体类对象
Class> demo=Class.forName("com.reflect.Fruit");
Constructor>[] con = demo.getConstructors();
Fruit fruit1= (Fruit) demo.newInstance();
//通过构造函数实例对象
Fruit fruit2= (Fruit) con[2].newInstance("苹果","红色","14.5");
Fruit fruit3= (Fruit) con[0].newInstance("橙子","黄色");
System.out.println(fruit1);
System.out.println(fruit2);
System.out.println(fruit3);
结果:
//获得构造方法
Class> demo=Class.forName("com.reflect.Fruit");
//获得所有的构造方法
Constructor>[] constructors = demo.getConstructors();
for (int i = 0; i < constructors.length; i++) {
System.out.println(constructors[i]);
}
结果:
Class> demo=Class.forName("com.reflect.Fruit");
Method[] methods = demo.getMethods();
Method[] declaredMethods = demo.getDeclaredMethods();
System.out.println("=========本类所有的方法=========");
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
}
System.out.println("=========父类及本类的所有方法=========");
for (Method method : methods) {
System.out.println(method);
}
结果:
Class> demo=Class.forName("com.reflect.Fruit");
Fruit fruit= (Fruit) demo.newInstance();
//获取成员变量
Field name=demo.getDeclaredField("name");
Field color=demo.getDeclaredField("color");
Field price=demo.getDeclaredField("price");
//给成员变量赋值
name.set(fruit, "苹果");
color.set(fruit,"红色");
price.set(fruit,"8.8");
fruit.getInfo();
结果:
Class> demo=Class.forName("com.reflect.Fruit");
Fruit fruit= (Fruit) demo.newInstance();
//动态获得方法名称及参数类型
Method method=demo.getDeclaredMethod("outInfo", String.class, Integer.TYPE);
//动态实现方法
method.invoke(fruit,"榴莲",39);
结果: