反射(Reflect):在运行时动态访问类与对象的技术。 Java反射技术都在java.lang.reflect包中。
现从下面的代码来看一下反射的好处:
public interface MathOperation {
public float operate(int a, int b);
}
public class Subtraction implements MathOperation{
@Override
public float operate(int a, int b){
System.out.println("执行减法运算");
return a - b;
}
}
public class Addition implements MathOperation{
@Override
public float operate(int a, int b){
System.out.println("执行加法运算");
return a + b;
}
}
import java.util.Scanner;
public class ReflectSample {
public static void Case1(){
Scanner scanner = new Scanner(System.in);
System.out.print("请输入计算类目:");
String op = scanner.next();
System.out.print("请输入a:");
int a = scanner.nextInt();
System.out.print("请输入b:");
int b = scanner.nextInt();
MathOperation mathOperation = null;
if (op.equals("Addition")){
mathOperation = new Addition();
}else if (op.equals("Subtraction")){
mathOperation = new Subtraction();
}else if (op.equals("Multiplication")){
mathOperation = new Multiplication();
} else {
System.out.println("无效的计算类");
return;
}
float result = mathOperation.operate(a,b);
System.out.print(result);
}
public static void Case2(){
Scanner scanner = new Scanner(System.in);
System.out.print("请输入计算类目:");
String op = scanner.next();
System.out.print("请输入a:");
int a = scanner.nextInt();
System.out.print("请输入b:");
int b = scanner.nextInt();
MathOperation mathOperation = null;
try {
mathOperation =(MathOperation) Class.forName("com.company.reflect." + op).newInstance();
} catch (Exception e){
System.out.println("无效的计算类");
return;
}
float result = mathOperation.operate(a, b);
System.out.println(result);
}
public static void main(String[] args) {
ReflectSample.Case2();
}
}
通过上面的代码可以看出使用反射技术一行代码就可以代替上面的else if语句,而且再添加除运算等不需要再修改代码,这是应该反射是运行时创建。
反射的核心类
1.Class类 2.Constructor构造方法类 3.Method方法类 4.Field成员变量类
一、Class类的核心方法
1.Class.forName() 静态方法,用于获取指定Class对象 2.ClassObj.newInstance() 通过默认构造方法创建新的对象 3.ClassObj.getConstructor() 获取构造方法Constructor对象 4.ClassObj.getMethod() 获取方法Method对象 5.ClassObj.getField() 获取成员变量Field对象 注:ClassObj表示返回的时Object类型。 首先先建立一个实体类。
package com.company.reflect.entity;
public class Employee {
static {
System.out.println("Employee类已被加载到jvm,并以初始化");
}
private Integer eno;
public String ename;
private Float salary;
private String dname;
public Employee(){
System.out.println("Employee默认构造方法已被执行");
}
public Employee(Integer eno, String ename, Float salary, String dname){
this.eno = eno;
this.ename = ename;
this.salary = salary;
this.dname = dname;
System.out.println("Employee带参构造方法已被执行");
}
public Integer getEno() {
return eno;
}
public void setEno(Integer eno) {
this.eno = eno;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public Float getSalary() {
return salary;
}
public void setSalary(Float salary) {
this.salary = salary;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
@Override
public String toString() {
return "Employee{" +
"eno=" + eno +
", ename='" + ename + '\'' +
", salary=" + salary +
", dname='" + dname + '\'' +
'}';
}
public Employee updateSalary(Float val){
this.salary = this.salary + val;
System.out.println(this.ename + "调薪至" + this.salary + "元");
return this;
}
}
下面是各个反射类的使用:
package com.company.reflect;
import com.company.reflect.entity.Employee;
public class ClassSample {
public static void main(String[] args) {
try {
Class employeeClass = Class.forName("com.company.reflect.entity.Employee");
System.out.println("Employee已被加载到JVM");
Employee emp =(Employee) employeeClass.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
二、Constructor构造方法类的核心方法
1.ConstructorObj.newInstance() 通过对于的构造方法创建对象
package com.company.reflect;
import com.company.reflect.entity.Employee;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class ConstructorSample {
public static void main(String[] args) {
try {
Class employeeClass = Class.forName("com.company.reflect.entity.Employee");
Constructor constructor = employeeClass.getConstructor(new Class[]{
Integer.class, String.class, Float.class, String.class
});
Employee employee =(Employee) constructor.newInstance(new Object[]{
100,"李磊",1000f,"研发部"
});
System.out.println(employee);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
三、Method方法类的核心方法
1.methodObj.invoke() 调用指定对象的对应方法
package com.company.reflect;
import com.company.reflect.entity.Employee;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class MethodSample {
public static void main(String[] args) {
try {
Class employeeClass = Class.forName("com.company.reflect.entity.Employee");
Constructor constructor = employeeClass.getConstructor(new Class[]{
Integer.class, String.class, Float.class, String.class
});
Employee employee = (Employee) constructor.newInstance(new Object[]{
200, "王五" , 5000f , "营销部"
});
Method updateSalaryMethod = employeeClass.getMethod("updateSalary", 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 (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
四、Field成员变量类的主要方法
1.fieldObj.set() 为某对象成员变量赋值 2.fieldObj.get() 获取某对象指定成员变量数值
package com.company.reflect;
import com.company.reflect.entity.Employee;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
public class FiledSample {
public static void main(String[] args) {
try {
Class employeeClass = Class.forName("com.company.reflect.entity.Employee");
Constructor constructor = employeeClass.getConstructor(new Class[]{
Integer.class, String.class, Float.class, String.class
});
Employee employee =(Employee) constructor.newInstance(new Object[]{
100,"玉龙",1000f,"研发部"
});
Field enameField = employeeClass.getField("ename");
String ename = (String)enameField.get(employee);
System.out.println("ename:" + ename);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}
getDeclared系列的方法可以获取私有的方法和属性
package com.company.reflect;
import com.company.reflect.entity.Employee;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class getDeclaredSample {
public static void main(String[] args) {
try {
Class employeeClass = Class.forName("com.company.reflect.entity.Employee");
Constructor constructor = employeeClass.getConstructor(new Class[]{
Integer.class, String.class, Float.class, String.class
});
Employee employee =(Employee) constructor.newInstance(new Object[]{
102,"孜韦",1002f,"老鸨部"
});
Field[] fields = employeeClass.getDeclaredFields();
for (Field field : fields){
if (field.getModifiers() == 1){
Object val = field.get(employee);
System.out.println(field.getName() + ":" + val);
} else if (field.getModifiers() == 2){
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();
}
}
}
|