2021-05-22

本文详细介绍了Java反射机制,包括Class类、Field类、Method类和Constructor类的使用,展示了如何通过反射获取类信息、创建对象并调用方法。通过两个示例,演示了如何利用反射实现解耦,动态加载和执行不同促销类的方法。
摘要由CSDN通过智能技术生成

反射机制:在运行状态下,动态获取信息,动态生成实例对象和动态调用对象方法的功能

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");
    }
}```


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值