反射机制:在运行状态下,动态获取信息,动态生成实例对象和动态调用对象方法的功能
java.lang包
Class类:反射的核心类:可获取类的属性,方法等信息,生成类的实例
Java。lang.reflect包
(1)Field类:表示类的成员变量,可来获取和设置类的属性值
(2)Methods类:表示类的方法,可用来获取类中的方法信息
(3)Constructor类:表示类的构造方法
基于反射生成类的实例
获取方法:
1.Class 类 getConstructor(Class[]parameterTypes) 返回一个构造方法对象
2.通过Constructor-newInstance(Object[] initargs) 可生成类的实例
3.通过**Method-invoke(Object obj,Object[] args),**可在具有指定参数的方法对象上调用此方法对象表示的的基础方法
构造方法构造对象,再用对象的Method对应的invoke()方法调用方法,完成这三步就可以为完成通过反射获取或实例化类的对象,然后调用对象相应方法
例1:
``
package JavaHigh.Reflect1;
public class Person {
private int age ;
private String name;
public String address;
public Person() {
}
public Person(int age, String name, String address) {
this.age = age;
this.name = name;
this.address = address;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
private void privateMethod1(){
System.out.println(this.getName()+","+this.getAge()+","+this.getAddress());
}
public void showInfo(){
System.out.println(this.getName()+","+this.getAge()+","+this.getAddress());
}
}
package JavaHigh.Reflect1;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test {
//基于反射, 获取类的相关信息(属性,方法)
public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {
//第一步:获取Class 对象
Class c = null;
try {
c = Class.forName("JavaHigh.Reflect1.Person");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//第二步:调用Class的相应方法
//获取Person类的相应属性
Field[] fields = c.getFields(); //所有访问的公共字段
-
Field address = c.getField("address"); //特定的公共字段
System.out.println(address.getName());
//所有可访问的公共对象
Field[] fields2 = c.getDeclaredFields(); //所有字段
//第三步: 调用相应反射API, 完成需求
for (Field f : fields) {
System.out.println(f.getName());
}
for (Field f : fields2) {
System.out.println(f.getName());
}
System.out.println("***************************");
Method[] methods = c.getMethods(); //包括所有公共方法, 包括继承来的方法
for (Method method : methods) {
System.out.println(method.getName());
}
System.out.println("*****************************");
Method[] dm = c.getDeclaredMethods(); //包括所有方法, 但是不包括继承来的方法
for (Method method : dm) {
System.out.println(method.getName());
}
//获取构造方法对象
//获取Perosn的无参构造方法对象
System.out.println("*********利用构造方法构造对象******");
try {
//获取构造方法对象
//获取Perosn的无参构造方法对象
Constructor constructor = c.getConstructor();
// //获取Perosn的带参构造方法对象
Constructor constructor2 = c.getConstructor(new Class[]{int.class,String.class,String.class});
//根据构造方法对象完成类的对象实例化
Object obj = constructor.newInstance();
Object obj2 = constructor2.newInstance(new Object[]{18,"张三","北京朝阳"});
//通过实例调用相应方法
//1.获取相应的方法Method对象,第一个参数:方法名, 第二个参数:方法中的参数类型, 无参为null
//带参方法的写法
//如果方法中有int, String类型的参数,如下:
// Method method = c.getMethod("showInfo", new Class[]{int.class,String.class});
//无参方法的写法
Method method = c.getMethod("showInfo", null);
//2-调用相应方法
method.invoke(obj, null);
method.invoke(obj2, null);
//根据构造方法对象完成类的对象
} catch (Exception e) {
e.printStackTrace();
}
}
}
例2:通过反射应用解耦
实现步骤:
①获取类的Class对象
②根据Class获取促销类的构造方法
③根据构造方法完成对象实例化
④调用相应方法
package JavaHigh.reflect;
//儿童节促销方案
public class ChildrenDayPS {
public ChildrenDayPS() {
}
public double promoteSales(String productId){
System.out.println("编号:"+productId+"的商品打六折");
return 0.6;
}
}
package JavaHigh.reflect;
public class NationalDayPs {
public NationalDayPs() {
}
public double promoteSales(String productId){
System.out.println("编号:"+productId+"的商品价格打七折");
return 0.7;
}
}
方法一:方式实现的方法`
package JavaHigh.reflect;
import javax.imageio.stream.ImageInputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class ProductSale {
//利用反射创建不同的促销类实例, 调用相应的商品促销方法
public void productSale(String productId){
//不同节日调用不同促销
//儿童节促销方案
ChildrenDayPS childrenDayPS = new ChildrenDayPS();
double discount = childrenDayPS.promoteSales(productId);
System.out.println("节日折扣为:"+discount);
/*
//国庆节促销方案
NationalDayPs nationalDayPs = new NationalDayPs();
double discount1 = nationalDayPs.promoteSales(productId);
System.out.println("节日折扣为:"+discount);*/
}
public static void main(String[] args) {
ProductSale ps = new ProductSale();
ps.promoteSales("006");
}
}```
方法二:反射的方法```
package JavaHigh.reflect;
import javax.imageio.stream.ImageInputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class ProductSale {
//利用反射创建不同的促销类实例, 调用相应的商品促销方法
public void productSale(String productId){
//不同节日调用不同促销
//儿童节促销方案
ChildrenDayPS childrenDayPS = new ChildrenDayPS();
double discount = childrenDayPS.promoteSales(productId);
System.out.println("节日折扣为:"+discount);
/*
//国庆节促销方案
NationalDayPs nationalDayPs = new NationalDayPs();
double discount1 = nationalDayPs.promoteSales(productId);
System.out.println("节日折扣为:"+discount);*/
}
//利用反射,创建不同的促销类实例, 调用相应的商品存销方法
public void productSaleByf(String productId,String className){
//不同节日, 调用不同的促销方案--利用反射
try {
//获得相应类的Class对象
Class c = Class.forName(className);
//根据Class去获得构造方法对象
Constructor constructor = c.getConstructor();
//根据构造方法去实例化对象
Object obj = constructor.newInstance();
//调用相应对象的商品打折方法
Method method = c.getMethod("promoteSales",String.class);
Double discount = (Double)method.invoke(obj,productId);
System.out.println("节日折扣为:"+discount);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ProductSale ps = new ProductSale();
ps.productSaleByf("0001","JavaHigh.reflect.ChildrenDayPS");
ps.productSaleByf("0001","JavaHigh.reflect.NationalDayPs");
}
}```