b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

Java:一步步带你深入了解神秘的Java反射机制(2)

电脑杂谈  发布时间:2019-07-08 15:15:39  来源:网络整理

image.png

实例2:利用反射调用类的构造函数


<-- 测试类定义-->
public class Student {
    // 无参构造函数
    public Student() {
        System.out.println("调用了无参构造函数");
    }
    // 有参构造函数
    public Student(String str) {
        System.out.println("调用了有参构造函数");
    }
    private String name;
}
<-- 利用反射调用构造函数 -->
        // 1. 获取Student类的Class对象
        Class studentClass studentClass = Student.class;
        // 2.1 通过Class对象获取Constructor类对象,从而调用无参构造方法
        // 注:构造函数的调用实际上是在newInstance(),而不是在getConstructor()中调用
        Object mObj1 = studentClass.getConstructor().newInstance();
        // 2.2 通过Class对象获取Constructor类对象(传入参数类型),从而调用有参构造方法
        Object mObj2 = studentClass.getConstructor(String.class).newInstance("Carson");

实例3:利用反射调用类对象的方法

<-- 测试类定义-->
public class Student {
    public Student() {
        System.out.println("创建了一个Student实例");
    }
    // 无参数方法
    public void setName1 (){
        System.out.println("调用了无参方法:setName1()");
    }
    // 有参数方法
    public void setName2 (String str){
        System.out.println("调用了有参方法setName2(String str):" + str);
    }
}
<-- 利用反射调用方法 -->
        // 1. 获取Student类的Class对象
        Class studentClass = Student.class;
        // 2. 通过Class对象创建Student类的对象
        Object  mStudent = studentClass.newInstance();
        // 3.1 通过Class对象获取方法setName1()的Method对象:需传入方法名
        // 因为该方法 = 无参,所以不需要传入参数
        Method  msetName1 = studentClass.getMethod("setName1");
        // 通过Method对象调用setName1():需传入创建的实例
        msetName1.invoke(mStudent);
        // 3.2 通过Class对象获取方法setName2()的Method对象:需传入方法名 & 参数类型
        Method msetName2 = studentClass.getMethod("setName2",String.class);
       // 通过Method对象调用setName2():需传入创建的实例 & 参数值
        msetName2.invoke(mStudent,"Carson_Ho");

关于 简单工厂模式的介绍 & 使用 请看文章:简单工厂模式(SimpleFactoryPattern)- 最易懂的设计模式解析

步骤1. 创建抽象产品类的公共接口

Product.java

java反射机制_java反射内存_java 反射 数组类型

abstract class Product{
    public abstract void show();
}
<-- 具体产品类A:ProductA.java -->
public class  ProductA extends  Product{
    @Override
    public void show() {
        System.out.println("生产出了产品A");
    }
}
<-- 具体产品类B:ProductB.java -->
public class  ProductB extends  Product{
    @Override
    public void show() {
        System.out.println("生产出了产品B");
    }
}

步骤3. 创建工厂类

Factory.java

public class Factory {
    // 定义方法:通过反射动态创建产品类实例
    public static Product getInstance(String ClassName) {
        Product concreteProduct = null;
        try {
            // 1. 根据 传入的产品类名 获取 产品类类型的Class对象
            Class product_Class = Class.forName(ClassName);
            // 2. 通过Class对象动态创建该产品类的实例
            concreteProduct = (Product) product_Class.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 3. 返回该产品类实例
        return concreteProduct;
    }
}

TestReflect.java

public class TestReflect {
    public static void main(String[] args) throws Exception {
       // 1. 通过调用工厂类的静态方法(反射原理),从而动态创建产品类实例
        // 需传入完整的类名 & 包名
        Product concreteProduct = Factory.getInstance("scut.carson_ho.reflection_factory.ProductA");
        // 2. 调用该产品类对象的方法,从而生产产品
        concreteProduct.show();
    }
}

如此一来,通过采用反射机制(通过 传入子类名称 & 动态创建子类实例),从而使得在增加产品接口子类的情况下,也不需要修改工厂类的逻辑 & 增加系统复杂度

步骤1:创建抽象产品类的公共接口

Product.java

abstract class Product{
    public abstract void show();
}

java反射机制_java反射内存_java 反射 数组类型

<-- 具体产品类A:ProductA.java -->
public class  ProductA extends  Product{
    @Override
    public void show() {
        System.out.println("生产出了产品A");
    }
}
<-- 具体产品类B:ProductB.java -->
public class  ProductB extends  Product{
    @Override
    public void show() {
        System.out.println("生产出了产品B");
    }
}

Factory.java

public class Factory {
    // 定义方法:通过反射动态创建产品类实例
    public static Product getInstance(String ClassName) {
        Product concreteProduct = null;
        try {
            // 1. 根据 传入的产品类名 获取 产品类类型的Class对象
            Class product_Class = Class.forName(ClassName);
            // 2. 通过Class对象动态创建该产品类的实例
            concreteProduct = (Product) product_Class.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 3. 返回该产品类实例
        return concreteProduct;
    }
}

步骤4:创建属性配置文件

Product.properties

// 写入抽象产品接口类的子类信息(完整类名)
ProductA = scut.carson_ho.reflection_factory.ProductA
ProductB = scut.carson_ho.reflection_factory.ProductB

若没assets文件夹,则自行创建

步骤6:在动态创建产品类对象时,动态读取属性配置文件从而获取子类完整类名

TestReflect.java

public class TestReflect {
    public static void main(String[] args) throws Exception {
        // 1. 读取属性配置文件
        Properties pro = new Properties() ;
        pro.load(this.getAssets().open("Product.properties"));
        // 2. 获取属性配置文件中的产品类名
        String Classname = pro.getProperty("ProductA");
        // 3. 动态生成产品类实例
        Product concreteProduct = Factory.getInstance(Classname);
        // 4. 调用该产品类对象的方法,从而生产产品
        concreteProduct.show();
}

如果有同学对代理模式,静态代理和动态代理这些概念比较模糊,请先阅读博主的另一篇文章《一步一步学设计模式——代理模式》。 java中常见的aop技术有两个,分别是filter和代理模式(也可以称为过滤器和),filter是基于回调函数(请看《java回调机制解析》),代理模式是基于java反射技术,代理模式又分为静态代理和动态代理,动态代理就是的简单实现。健全信息报送机制,通过《决策参考》、《改革动态》和《百色工作》全面宣传全面深化改革工作,全年编印《决策参考》4期、《改革动态》12期,有力推进全面深化改革工作开展。


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-111387-2.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    热点图片
    拼命载入中...