反射:反射机制是在运行状态中
1,对于任意一个类都能知道它的所有属性和方法
2,对于任意一个对象都能调用它的所有方法和属性
反射的功能:
1,在运行时判断任意一个对象所属的类
2,在运行时构造任意一个类的对象
3,在运行时判断任意一个类所具有的的成员变量和方法
4,在运行时调用任意一个对象的方法
5,生成动态代理
获取反射对象的三种方式(Class为反射的入口,本质上讲,一个对象对应的一个不变的、唯一的Class对象)
1,Class.forName(全类名)
2,类名.class
3,对象.getClass()
编写两个简单的接口:
package com.yun.demo1;
public interface PersonInter1 {
public void msg();
}
package com.yun.demo1;
public interface PersonInter2 {
public void msg2();
}
编写Superman类去实现这两个接口:
package com.yun.demo1;
public class Superman implements PersonInter1,PersonInter2 {
private int id;
private String name;
private char grade;
public String sMsg;
@Override
public void msg() {
System.out.println("接口1返回信息!");
}
@Override
public void msg2() {
System.out.println("接口2返回信息!");
}
public Superman() {
System.out.println("Superman的无参构造方法!");
}
public Superman(int id, String name, char grade) {
this.id = id;
this.name = name;
this.grade = grade;
System.out.println("Superman的有参构造方法!");
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getGrade() {
return grade;
}
public void setGrade(char grade) {
this.grade = grade;
}
public static void myStatic() {
System.out.println("Superman的静态方法!");
}
private static void privateMethod() {
System.out.println("Superman的私有静态方法!");
}
private static void privateMethod2(String name) {
System.out.println("Superman带有名称的私有静态方法!" + name);
}
@Override
public String toString() {
return "Superman{" +
"编号=" + id +
", 姓名='" + name + '\'' +
", 等级=" + grade +
'}';
}
}
编写一个class.txt文件(用于之后的动态执行类与方法)
classname=com.yun.demo1.Superman
methodname=privateMethod
准备完毕后编写测试ReflectDemo1类(来获取对象,方法,属性等)
package com.yun.demo1;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectDemo1 {
/**
* 获取反射对象
*/
public static void getObj(){
//Class.forName(全类名)
Class<?> class1 = null;
try {
class1 = Class.forName("com.yun.demo1.Superman");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//类名.class
Class<?> class2 = Superman.class;
//对象.getClass()
Superman sup = new Superman();
Class<?> class3 = sup.getClass();
//比较拿到的对象
System.out.println(class1==class2);
System.out.println(class1==class3);
System.out.println(class2==class3);
}
/**
* 获取所有方法
*/
public static void getMethod(){
//以Class.forName(全类名)的方式为例
Class<?> pClass = null;
try {
pClass = Class.forName("com.yun.demo1.Superman");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//获取所有公共方法(本类,父类,接口中的public方法)
Method[] methods = pClass.getMethods();
for (Method method:methods) {
System.out.println(method);
}
System.out.println("**************************************");
//获取当前类的所有方法(本类的,忽略访问修饰符)
Method[] declaredMethods = pClass.getDeclaredMethods();
for (Method dmethod:declaredMethods) {
System.out.println(dmethod);
}
}
/**
* 获取所有接口(多实现所以接口可以返回多个)
*/
public static void getInter(){
//以Class.forName(全类名)的方式为例
Class<?> pClass = null;
try {
pClass = Class.forName("com.yun.demo1.Superman");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Class<?>[] interfaces = pClass.getInterfaces();
for (Class<?> inter:interfaces) {
System.out.println(inter);
}
}
/**
* 获取父类(单继承所以父类只能返回一个)
*/
public static void geFather(){
//以Class.forName(全类名)的方式为例
Class<?> pClass = null;
try {
pClass = Class.forName("com.yun.demo1.Superman");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Class<?> superclass = pClass.getSuperclass();
System.out.println(superclass);
}
/**
* 获取所有公共的构造方法
*/
public static void geCons(){
//以Class.forName(全类名)的方式为例
Class<?> pClass = null;
try {
pClass = Class.forName("com.yun.demo1.Superman");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Constructor<?>[] constructors = pClass.getConstructors();
for (Constructor<?> constructor:constructors) {
System.out.println(constructor);
}
}
/**
* 获取所有的属性
*/
public static void geParam(){
//以Class.forName(全类名)的方式为例
Class<?> pClass = null;
try {
pClass = Class.forName("com.yun.demo1.Superman");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//获取所有的公共属性(与拿到的公共方法一样)
Field[] fields = pClass.getFields();
for (Field field:fields) {
System.out.println(field);
}
System.out.println("**************************************");
//获取当前类的所有属性
Field[] declaredFieldsfields = pClass.getDeclaredFields();
for (Field dfield:declaredFieldsfields) {
System.out.println(dfield);
}
}
/**
* 获取当前反射所代表类(接口)的对象(实例)
*/
public static void getExample() throws IllegalAccessException, InstantiationException {
//以Class.forName(全类名)的方式为例
Class<?> pClass = null;
try {
pClass = Class.forName("com.yun.demo1.Superman");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Object instance = pClass.newInstance();
//强转成Superman,再调用Superman的方法,成功则代表instance就是Superman
Superman s = (Superman)instance;
s.msg2();
}
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
getObj();
getMethod();
getInter();
geFather();
geCons();
geParam();
getExample();
}
}
编写测试ReflectDemo2类(来操作对象,方法,属性等)
package com.yun.demo1;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Properties;
public class ReflectDemo2 {
/**
* 操作对象
*/
public static void doObj() throws IllegalAccessException, InstantiationException {
//以Class.forName(全类名)的方式为例
Class<?> pClass = null;
try {
pClass = Class.forName("com.yun.demo1.Superman");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Object instance = pClass.newInstance();
Superman s = (Superman)instance;
s.setId(1);
s.setName("钢铁侠");
s.setGrade('S');
System.out.println(s.toString());
}
/**
* 操作属性和方法
*/
public static void doParam() throws NoSuchFieldException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
//以Class.forName(全类名)的方式为例
Class<?> pClass = null;
try {
pClass = Class.forName("com.yun.demo1.Superman");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Object instance = pClass.newInstance();
Superman s = (Superman)instance;
Field idField = pClass.getDeclaredField("id");
//Superman中的id是私有的,所以必须修改访问权限才能访问(方法/属性.setAccessible(true);)
idField.setAccessible(true);
//此处相当于s.setId(2);
idField.set(s,2);
System.out.println(s.getId());
System.out.println("**************************************");
//调用无参数的私有方法
Method privateMethod = pClass.getDeclaredMethod("privateMethod", null);
privateMethod.setAccessible(true);
privateMethod.invoke(s,null);
System.out.println("**************************************");
//调用带参数的私有方法
Method privateMethod2 = pClass.getDeclaredMethod("privateMethod2", String.class);
privateMethod2.setAccessible(true);
privateMethod2.invoke(s,"美国队长");
}
/**
* 操作构造方法
*/
public static void doConMethod() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//以Class.forName(全类名)的方式为例
Class<?> pClass = null;
try {
pClass = Class.forName("com.yun.demo1.Superman");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Constructor<?> declaredConstructor = pClass.getDeclaredConstructor(int.class, String.class, char.class);
System.out.println(declaredConstructor);
//若需要调用私有的构造要打开访问权限declaredConstructor.setAccessible(true);
Superman instance = (Superman) declaredConstructor.newInstance(3,"雷神",'S');
System.out.println(instance);
}
/**
* 动态加载类名和方法
*/
public static void dynamic() throws IOException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
Properties prop = new Properties();
prop.load(new FileReader("class.txt"));
String className = prop.getProperty("classname");
String methodName = prop.getProperty("methodname");
//以Class.forName(全类名)的方式为例
Class<?> pClass = null;
try {
pClass = Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Method method = pClass.getMethod(methodName);
method.invoke(pClass.newInstance());
}
/**
* 反射可以越过泛型检查
*/
public static void addList() throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
Class<?> listClass = list.getClass();
Method method = listClass.getMethod("add", Object.class);
method.invoke(list,"惊奇队长");
System.out.println(list);
}
public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException, IOException {
doObj();
doParam();
doConMethod();
dynamic();
addList();
}
}