文章摘要
一、反射及作用
1、什么是 反射(Reflect)👻
1、反射( Reflect |
/rɪˈflekt/
)是在运动时
动态访问类与对象的技术|
2、反射是JDK1.2版本后的高级特性,隶属于java.lang.reflect|
3、大多数Java框架都基于反射实现参数配置、动态注入等特性|
4、在运行时 动态创建对象 执行方法 访问成员变量
运动时动态访问类与对象
——>>> 代码演示🚴🚴🚴
// 在不改变源代码的情况下,创建新的 类 动态加载该类 并使用该 类
//1.定义一个四则运算 接口
public interface YunSuan{
public float function(int x , int y);
}
//2.创建 相加 的 类 实现上面的接口 实现接口方法
public class Add implements YunSun {
@Override
public float function(int a , int b) {
return a + b;
}
}
//3. 测试类
public class Test {
public static void main(String[] args) {
EZ();
}
//创建测试方法 再 利用反射 创建对象
public static void EZ(){
Scanner scanner = new Scanner(System.in);
System.out.print("请输入计算类名:");
String LOL = scanner.next();
System.out.print("请输入a:");
int a = scanner.nextInt();
System.out.print("请输入b:");
int b = scanner.nextInt();
//获取某一个类 创建 获取 类的对象
YunSun YS = (YunSuan) Class.forName("zzz.yyy.xxx." + LOL).newInstance();
//控制台可以显示结果
System.out.println(YS.function(a, b));
}
}
两数相加
:使 LOL = Add 即可。总结:代码没写死 LOL的值是动态的。若添加 四则运算 其他功能 无需改上面的代码,只要 创建相应的类即可。|
例:两数相减
:创建同路目录下 相减的类
并实现接口方法即可。
二、Class核心方法
Class.forName()
静态方法 用于获取指定Class对象例如获取到之后 是 =》classObj
classObj.newInstance()
通过 默认 构造方法创建新建的对象 返回Object所以下面强转了
classObj.getMethod()
获取指定的public修饰方法Method对象
classObj.getField()
获取指定的public修饰成员变量Field对象
相关 代码演示如下: 👇 👇 👇
1、Class 类
Class对象
是描述 其他类
的 一个对象 那么Class就是… ( 真玄乎~ )
public class Employee {
private Integer eno;
public String ename;
private Float salary;
private String dname;
//简洁效果 此处省略
//无参构造、带参构造
//set \ get 方法
// toString
public Employee function(Float val){
this.salary = this.salary + val;
System.out.println(this.ename + "调薪至" + this.salary + "元");
return this;
}
}
Class.forName()
静态方法 用于获取指定Class对象例如获取到之后 是 =》classObj
classObj.newInstance()
通过 默认 构造方法创建新建的对象 返回Object所以下面强转了
public class Test {
public static void main(String[] args) {
try {
//Class.forName()方法将指定的类加载到jvm,并返回对应Class对象
Class employeeClass = Class.forName("zzz.yyy.xxx.aaa.Employee");
System.out.println("Employee已被加载到jvm");
//newInstance通过默认构造方法创建新的对象
Employee emp = (Employee)employeeClass.newInstance();
System.out.println(emp);//可以得到一个对象
} catch (ClassNotFoundException e) {
//类名与类路径书写错误是抛出"类无法找到"异常
e.printStackTrace();
} catch (IllegalAccessException e) {
//非法访问异常,当在作用域外访问对象方法或成员变量时抛出
e.printStackTrace();
} catch (InstantiationException e) {
//对象无法被实例化,抛出"实例化异常"
e.printStackTrace();
}
}
}
2、 Constructor构造方法类
classObj.getConstructor()
获取指定的public修饰构造方法Constructor对象例如获取到之后 是 =》constructorObj
constructorObj.newInstance()
通过 对应 的构造方法创建对象
public class ConstructorSample {
public static void main(String[] args) {
try {
Class employeeClass = Class.forName("zzz.yyy.xxx.aaa.Employee");
Constructor constructor = employeeClass.getConstructor(new Class[]{
// .class =》
Integer.class,String.class,Float.class,String.class
});
Employee employee = (Employee) constructor.newInstance(new Object[]{
007,"终结者",2500f,"未来世界"
});
System.out.println(employee);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
//没有找到与之对应格式的方法
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
//当被调用的方法的内部抛出了异常而没有被捕获时
e.printStackTrace();
}
}
}
3、 Method方法类
classObj.getMethod()
获取指定的public修饰方法Method对象例如获取到之后 是 =》methodObj
methodObj.invoke()
调用指定对象的对应方法
public class MethodSample {
public static void main(String[] args) {
try {
Class employeeClass = Class.forName("zzz.yyy.xxx.aaa.Employee");
Constructor constructor = employeeClass.getConstructor(new Class[]{
Integer.class,String.class,Float.class,String.class
});
Employee employee = (Employee)constructor.newInstance(new Object[]{
007,"终结者",3000f,"未来世界"
});
Method updateSalaryMethod = employeeClass.getMethod("function" , new Class[]{
Float.class
});
Employee employee1 = (Employee)updateSalaryMethod.invoke(employee,new Object[]{1000f});
System.out.println(employee1);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
4、 Field成员变量类
classObj.getField()
获取指定的public修饰成员变量Field对象例如获取到之后 是 =》fieldObj
fieldObj.set()
为某对象指定成员属性赋值
fieldObj.get()
获取某对象指定成员变量数值
public class FieldSample {
public static void main(String[] args) {
try {
Class employeeClass = Class.forName("zzz.yyy.xxx.aaa.Employee");
Constructor constructor = employeeClass.getConstructor(new Class[]{
Integer.class,String.class,Float.class,String.class
});
Employee employee = (Employee) constructor.newInstance(new Object[]{
007,"终结者",3000f,"未来世界"
});
Field enameField = employeeClass.getField("ename");
enameField.set(employee,"幽灵猎手");
String ename = (String)enameField.get(employee);
System.out.println("ename:" + ename);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
//没有找到对应成员变量时抛出的异常
e.printStackTrace();
}
}
}
5、 getDeclared系列方法说明
可以获取所有的修饰符对象,当对私有的 进行访问或调用会抛出无法访问的异常
getDeclared
Constructor(s)|Method(s)|Field(s)获取对应对象
public class getDeclaredSample {
public static void main(String[] args) {
try {
Class employeeClass = Class.forName("zzz.yyy.xxx.aaa.Employee");
Constructor constructor = employeeClass.getConstructor(new Class[]{
Integer.class, String.class, Float.class, String.class
});
Employee employee = (Employee) constructor.newInstance(new Object[]{
007,"终结者",3000f,"未来世界"
});
//获取当前类所有成员变量
Field[] fields = employeeClass.getDeclaredFields();
for(Field field : fields){
// System.out.println(field.getName());
if(field.getModifiers() == 1){ //pubilc修饰
Object val = field.get(employee);
System.out.println(field.getName() + ":" + val);
}else if(field.getModifiers() == 2){ //private修饰
String methodName = "get" + field.getName().substring(0,1).toUpperCase()
+ field.getName().substring(1);
Method getMethod = employeeClass.getMethod(methodName);
Object ret = getMethod.invoke(employee);
System.out.println(field.getName() + ":" + ret);
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
总结
侧重点在于反射的主要流程,能快速认识反射。粗略总结以上内容。码字不易,如果对您有所帮助不妨留个赞赞~🐬🐬🐬
我爱你 ~ 有时候我希望你的一生,能被拍成一部漫长的电影,我就比你晚出生一百年,一辈子只做一件事,独自坐在房间里对着墙上的屏幕,用我的一生把你的一生慢慢看完。💕💕💕
🙏愿: 宇宙的尽头没有 反射。