【java高级程序设计】反射||自食用

30 篇文章 1 订阅
16 篇文章 0 订阅

目录

一、 理解

   》若新增策略,可继承该接口、增加记录

二、 深入反射

代码:

1. 显示加载指定类

通过.forName()加载类

代码:

2. 通过反射实例化类

(1) Class类的newInstance()方法

代码:

(2) Constructor类的newInstance()方法

代码:

3. 通过反射执行方法

Method里提供了.invoke(Object obj, Object…args)

代码:

核心代码:

4. 通过反射修改属性

Field里提供了.set(Object obj, Object value)

代码:

核心代码:

5. 修改访问权限

setAccessible(true) 设置访问

 (1) Field属性修改

代码:

核心代码:

(2) Method方法修改

​ 

代码:

核心代码:


一、 理解

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);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值