目录
(2) Constructor类的newInstance()方法
Method里提供了.invoke(Object obj, Object…args)
Field里提供了.set(Object obj, Object value)
一、 理解
eg》市场促销活动的促销折扣会改变
》定义一个接口,传入原单价
》配置文件记录打折策略
》让程序读取配置文件,列出策列列表供用户选择
》若新增策略,可继承该接口、增加记录
二、 深入反射
代码:
package reflectL;
public abstract class Person {
public abstract String toString();
}
1. 显示加载指定类
通过.forName()加载类
代码:
package reflectL;
/**
* @author: y9
* @Date: 2021/09/28
*/
public class Bootstrap {
public static String className = "reflectL.Teacher";
public static void main(String[] args) {
try {
System.out.println("开始加载类");
Class clazz = Class.forName(className); //Class claz = Teacher.class(); 按需加载
System.out.println("类加载完毕");
}catch (ClassNotFoundException e ) {
e.printStackTrace();
}
}
}
开始加载类
类加载完毕
2. 通过反射实例化类
(1) Class类的newInstance()方法
代码:
package reflectL;
/**
* @author: y9
* @Date: 2021/09/28
*/
public class Bootstrap {
public static String className = "reflectL.Teacher";
public static void main(String[] args) {
try {
Class clazz = Class.forName(className); //Class claz = Teacher.class(); 按需加载
//通过Person获取Teacher【由父类获取子类】
Person person = (Person)clazz.newInstance();
System.out.println("newInstance as person" + person.toString());
//Teacher teacher = (Teacher) clazz.newInstance(); //不建议直接获取子类
}catch (Exception e ) {
e.printStackTrace();
}
}
}
newInstance as person[Position:nullSalary:0]
!tips:获取子类的时候,建议用父类由上往下获取类,不建议直接获取子类。
(2) Constructor类的newInstance()方法
代码:
package reflectL;
import java.lang.reflect.Constructor;
/**
* @author: y9
* @Date: 2021/09/28
*/
public class Bootstarp {
public static String className = "reflectL.Teacher";
public static void main(String[] args) {
try {
Class clazz = Class.forName(className); //Class claz = Teacher.class(); 按需加载
Constructor constructor = clazz.getConstructor();
//通过Person获取Teacher【由父类获取子类】
Person person = (Person)constructor.newInstance();
System.out.println("newInstance as person" + person.toString());
//Teacher teacher = (Teacher) clazz.newInstance(); //不建议直接获取子类
}catch (Exception e ) {
e.printStackTrace();
}
}
}
newInstance as person[Position:nullSalary:0]
3. 通过反射执行方法
动态地执行方法!
Method里提供了.invoke(Object obj, Object…args)
代码:
package reflectL;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
/**
* @author: y9
* @Date: 2021/09/28
*/
public class Bootstarp {
public static String className = "reflectL.Teacher";
public static void main(String[] args) {
try {
Class clazz = Class.forName(className); //Class claz = Teacher.class(); 按需加载
Constructor constructor = clazz.getConstructor(); //获取构造器
Object teacher = constructor.newInstance(); // 由Object获取Teacher实例
Method method = clazz.getMethod("speak", String.class); // 获取speak方法
method.invoke(teacher, "Lesson one!");
}catch (Exception e ) {
e.printStackTrace();
}
}
}
Speak:Lesson one!
核心代码:
Method method = clazz.getMethod("speak", String.class); // 获取speak方法
method.invoke(teacher, "Lesson one!");
4. 通过反射修改属性
动态地给属性赋值!
Field里提供了.set(Object obj, Object value)
代码:
package reflectL;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* @author: y9
* @Date: 2021/09/28
*/
public class Bootstarp {
public static String className = "reflectL.Teacher";
public static void main(String[] args) {
try {
Class clazz = Class.forName(className); //Class claz = Teacher.class(); 按需加载
Constructor constructor = clazz.getConstructor(); //获取构造器
Object teacher = constructor.newInstance(); // 由Object获取Teacher实例
//Method method = clazz.getMethod("speak", String.class); // 获取speak方法
//method.invoke(teacher, "Lesson one!");
System.out.println(teacher.toString());
Field field = clazz.getField("position");
field.set(teacher, "Master");
System.out.println(teacher.toString());
}catch (Exception e ) {
e.printStackTrace();
}
}
}
[Position:nullSalary:0]
[Position:MasterSalary:0]
核心代码:
Field field = clazz.getField("position");
field.set(teacher, "Master");
5. 修改访问权限
setAccessible(true) 设置访问
(1) Field属性修改
代码:
package reflectL;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* @author: y9
* @Date: 2021/09/28
*/
public class Bootstarp {
public static String className = "reflectL.Teacher";
public static void main(String[] args) {
try {
Class clazz = Class.forName(className); //Class claz = Teacher.class(); 按需加载
Constructor constructor = clazz.getConstructor(); //获取构造器
Object teacher = constructor.newInstance(); // 由Object获取Teacher实例
System.out.println(teacher.toString());
Field field = clazz.getDeclaredField("salary");
//field.set(teacher, 4000); //出错,没有权限修改private属性
field.setAccessible(true);
field.set(teacher, 5000);
System.out.println(teacher.toString());
}catch (Exception e ) {
e.printStackTrace();
}
}
}
[Position:nullSalary:0]
[Position:nullSalary:5000]
核心代码:
Field field = clazz.getDeclaredField("salary");
field.setAccessible(true);
field.set(teacher, 5000);
(2) Method方法修改
若未修改private方法权限,则抛出异常:
[Position:nullSalary:0]
java.lang.IllegalAccessException: class reflectL.Bootstarp (in module studentsa) cannot access a member of class reflectL.Teacher (in module studentsa) with modifiers "private"
at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:385)
at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:693)
at java.base/java.lang.reflect.Method.invoke(Method.java:556)
at studentsa/reflectL.Bootstarp.main(Bootstarp.java:24)
代码:
package reflectL;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* @author: y9
* @Date: 2021/09/28
*/
public class Bootstarp {
public static String className = "reflectL.Teacher";
public static void main(String[] args) {
try {
Class clazz = Class.forName(className); //Class claz = Teacher.class(); 按需加载
Constructor constructor = clazz.getConstructor(); //获取构造器
Object teacher = constructor.newInstance(); // 由Object获取Teacher实例
System.out.println(teacher.toString());
Method method = clazz.getDeclaredMethod("getSalary");
method.setAccessible(true); //修改权限
Integer salary = (Integer)method.invoke(teacher);
System.out.println("teacher salary" + salary);
}catch (Exception e ) {
e.printStackTrace();
}
}
}
[Position:nullSalary:0]
teacher salary0
核心代码:
Method method = clazz.getDeclaredMethod("getSalary");
method.setAccessible(true); //修改权限
Integer salary = (Integer)method.invoke(teacher);