反射,工厂模式

该类不能运行,执行Test方法,需要空构造函数

demo3: 调用指定构造方法

demo2: 调用默认构造方法

demo1: 获得.class 字节码对象,对应Class对象. 3种方法

通过反射获取成员变量,修改私有变量是可见的

通过反射的方式执行类中的方法

自动装配

工厂模式: 使用接口, 接收通过工厂类返回来的实例对象. 工厂类通过读取配置文件,来决定实例化哪个类

package com.xiaofan.test;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;

import org.junit.Test;

public class ClassTest {
    public ClassTest(int a) {
    }
    // 类构造实例,调用指定构造方法
    @Test
    public void demo3() throws ClassNotFoundException, SecurityException,
            NoSuchMethodException, IllegalArgumentException,
            InstantiationException, IllegalAccessException,
            InvocationTargetException {
        // 已知类情况下,通过new 创建实例
        ClassTest classTest = new ClassTest(10);
        // 1. 获得字节码对象
        Class c = Class.forName("com.xiaofan.test.ClassTest");
        // 2. 获得指定构造方法
        Constructor constructor = c.getConstructor(int.class);
        // 3、调用构造方法 获得对象
        Object o = constructor.newInstance(10);
    }
    // 类构造实例,默认构造方法
    @Test
    public void demo2() throws ClassNotFoundException, InstantiationException,
            IllegalAccessException {
        // 已知类情况下,通过new 创建实例
        ClassTest classTest = new ClassTest(10);
        // 未知类和对象情况下
        String classDescription = "com.xiaofan.test.ClassTest";
        Class c3 = Class.forName(classDescription);
        Object classTest2 = c3.newInstance(); // 执行默认构造方法
    }

    // 获得一个.class 字节码文件 对应Class类对象
    @Test
    public void demo1() throws ClassNotFoundException {
        // 已知类情况下 获得字节码对象
        Class c1 = ClassTest.class;
        // 已知一个对象,但是不知道这个对象属于哪个类,获得字节码对象
        Object o = new ArrayList();
        Class c2 = o.getClass(); // 等价于 ArrayList.class
        // 未知类和对象情况下
        String classDescription = "com.xiaofan.test.ClassTest";
        Class c3 = Class.forName(classDescription);
    }
}

-----------------------------------------------------------------------------------------------

通过反射获取成员变量,执行类中方法

package com.xiaofan.test;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.junit.Test;

public class FieldMethodTest {
    private int num;

    public void m(String s) {
        System.out.println("反射测试的方法!" + s);
    }
    /**
     * 通过反射的方式执行类中的方法
     */
    @Test
    public void demo2() throws ClassNotFoundException, InstantiationException,
            IllegalAccessException, SecurityException, NoSuchMethodException,
            IllegalArgumentException, InvocationTargetException {
        // 以前方式
        FieldMethodTest fieldMethodTest = new FieldMethodTest();
        fieldMethodTest.m("001");
        // 1. 获得Class对象
        Class c = Class.forName("com.xiaofan.test.FieldMethodTest");
        // 2、获得对象
        Object o = c.newInstance();
        // 3. 获得m对象反射中Method对象
        Method m = c.getMethod("m", String.class);
        // 4. 调用o对象m方法
        m.invoke(o, "008");
    }

    /**
     * 通过反射获取成员变量,修改私有变量是可见的
     */
    @Test
    public void demo1() throws ClassNotFoundException, SecurityException,
            NoSuchFieldException, InstantiationException,
            IllegalAccessException {
        // 以前方法操作变量
        FieldMethodTest fieldMethodTest = new FieldMethodTest();
        fieldMethodTest.num = 10;
        // 1、获得字节码文件
        Class c = Class.forName("com.xiaofan.test.FieldMethodTest");
        // 2、获得num成员变量 对应反射对象 Field
        Field[] fields = c.getFields(); // 获得所有public属性
        System.out.println(fields.length);
        Field[] fields2 = c.getDeclaredFields(); //获得所有成员变量
        System.out.println(fields2.length);
        Field field = c.getDeclaredField("num");
        // 3. 为num 赋值
        Object o = c.newInstance(); // 调用默认构造方法
        // 修改私有变量是 可见的
        field.setAccessible(true);
        field.set(o, 20);
        System.out.println(field.get(o));
    }
}

-------------------------------------------------------------------------------------------------------

自动装配

package com.xiaofan.test;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.junit.Test;

public class AutowireTest {
    @Test
    public void demo1() throws Exception {
        Map<String, String> map = new HashMap<String, String>();
        map.put("name", "小丽");
        map.put("hobby", "音乐");
        map.put("age", "20");
        Person person = new Person();
        autowire(person, map);
        System.out.println(person.getName());
        System.out.println(person.getHobby());
        User user = new User();
        autowire(user, map);
        System.out.println(user.getName());
        System.out.println(user.getAge());

    }

    public void autowire(Object o, Map<String, String> map) throws Exception {
        // 获得map 所有key
        Set<String> keys = map.keySet();
        // 获得Object中所有属性
        // 获得Class对象
        Class c = o.getClass();
        // 获得所有属性
        Field[] fields = c.getDeclaredFields();
        for (Field field : fields) {
            // 获得属性名称
            String fieldName = field.getName();
            // 判断属性名称是否存在于map的key
            if (map.containsKey(fieldName)) {
                // 完成属性封装
                String value = map.get(fieldName);
                // 修改私有属性可见性
                field.setAccessible(true);
                field.set(o, value);
            }
        }
    }
}

class User {
    private String name;
    private String age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

}

class Person {
    private String name;
    private String hobby;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getHobby() {
        return hobby;
    }

    public void setHobby(String hobby) {
        this.hobby = hobby;
    }

}

------------------------------------------------------------------------------------------------

工厂模式,测试类:

package com.xiaofan.demo;

import org.junit.Test;

import com.xiaofan.demo.impl.Fenggong;
import com.xiaofan.demo.impl.Liuqian;
import com.xiaofan.demo.impl.Wangfei;
import com.xiaofan.demo.impl.Yangliping;

public class EveningParty {

    /**
     * 使用工厂模式,从配置文件中实例化所需要的对象
     * @throws Exception
     */
    @Test
    public void demo2() throws Exception {
        // 对于估计要做事情,定义接口 ---- 不变的
        // 变化的是 实现类

        // 1. 歌曲类
        Singer singer = Factory.findSinger(); // 工厂
        singer.sing();
        // 2. 舞蹈类
        Dancer dancer = Factory.findDancer();
        dancer.dance();
        // 3、语言类
        Speaker speaker = Factory.findSpeaker();
        speaker.speak();
        // 4、动作类
        Actor actor = Factory.findActor();
        actor.action();
    }

    /**
     * 传统方式,紧密耦合
     */
    @Test
    public void demo1() {
        // 对于估计要做事情,定义接口 ---- 不变的
        // 变化的是 实现类

        // 1. 歌曲类
        Singer singer = new Wangfei(); // 紧密耦合
        singer.sing();
        // 2. 舞蹈类
        Dancer dancer = new Yangliping();
        dancer.dance();
        // 3、语言类
        Speaker speaker = new Fenggong();
        speaker.speak();
        // 4、动作类
        Actor actor = new Liuqian();
        actor.action();
    }
}

工厂类:

package com.xiaofan.demo;

import java.util.ResourceBundle;

import com.xiaofan.demo.impl.Liuqian;
import com.xiaofan.demo.impl.Yangliping;
import com.xiaofan.demo.impl.Zhaobenshan;

public class Factory {
    public static Singer findSinger() throws Exception {
        // return new Wangfei();
        // 上面是传统模式,下面使用工厂模式返回实例对象
        // className = com.xiaofan.demo.impl.Zhangxueyou
        // ResourceBundle: 资源包类,可以使用指定的语言环境.使用类加载器的方式加载配置文件
        String className = ResourceBundle.getBundle("party").getString("singer");
        Class c = Class.forName(className);
        return (Singer) c.newInstance();
    }

    public static Dancer findDancer() {
        return new Yangliping();
    }

    public static Speaker findSpeaker() {
        return new Zhaobenshan();
    }

    public static Actor findActor() {
        return new Liuqian();
    }

}

接口类(这里只paste了其中一个接口):

package com.xiaofan.demo;

public interface Singer {
    public void sing();
}

接口实现类(这里只paste了其中一个实现类):

package com.xiaofan.demo.impl;

import com.xiaofan.demo.Singer;

public class Zhangxueyou implements Singer {

    @Override
    public void sing() {
        System.out.println("张学友 演唱 一路有你!");
    }

}

配置文件:

singer = com.xiaofan.demo.impl.Zhangxueyou
dancer =com.xiaofan.demo.impl.Yangliping
speaker = com.xiaofan.demo.impl.Fenggong
actor =com.xiaofan.demo.impl.Liuqian

--------------------------------------------------------------------------------------------

时间: 2024-08-28 16:21:34

反射,工厂模式的相关文章

C#使用反射工厂模式遇到System.TypeLoadException

项目中,在运行另一个反射类时出现问题,未能从程序集中加载类 class PopUpActionFactory { public static InterfacePopUpAction getAction(String actionName) { InterfacePopUpAction action = null; actionName = "XSheet.Data.PopUpAction.PopUpAction" + actionName; //XNamedTable try { T

终极版:由简单工厂模式,升级到抽象工厂模式(用到反射)

前面两个已经学习简单三层到简单工厂模式的变化,但是简单工厂模式还是有个缺点,就是简单工厂中集合了所有的实例的创建.也不是很好. 现在想到使用抽象工厂的方式来实现这个: 我们在程序集中加上下面的代码: <appSettings> <!--命名空间--> <add key="DALNameSpace" value="DAL"/> <!--程序集--> <add key="DALAssembly"

工厂模式与反射

工厂模式与反射 定义一个接口以及两个实现了该接口的类: package Reflect; interface fruit{ public void eat(); } class Apple implements fruit{ public void eat(){ System.out.println("Apple Eat"); } } class Orange implements fruit{ public void eat(){ System.out.println("O

基于C#反射机制的工厂模式

简单介绍 反射提供了描写叙述程序集.模块和类型的对象(Type 类型). 能够使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或訪问其字段和属性. 假设代码中使用了特性.能够利用反射来訪问它们. 这里的类型信息包含类型的方法,变量名称.类型等信息. 基于反射机制的工厂模式 例如以下图所看到的,游戏中经常使用的掉落物模型,Item是基类,定义了一些基础属性,也定义了一些abstract方法. Food和Weapon继承自Item.表示一类Item.再下一层的类就定

工厂模式(Factory Pattern)和java反射机制优化思考

GOF的工厂模式是最基础的一种创建型设计模式,其适用于创建同一接口的不同实现子类, 其优点是:将使使用者更加方便使用,而不关心具体的创建逻辑 缺点是:每增加一个接口的子类,必须修改工程类的相关逻辑(后面我们用java的反射机制进行优化) 从上面UML图看到,我们设置了一个Shape接口,并且实现了三个子类,我们通过ShapeFactory来根据不同的名称返回不同的子类实例,通过FactoryPatternDemo进行的测试.逻辑很简单,不再详述. public class ShapeFactor

反射+抽象工厂模式

这里通过一个DEMO介绍反射配合抽象工厂模式的运用.大概业务背景就是在实际业务过程中,可能要替换数据库,具体代码如下: 1.User实体类 class User { private int id; private string name; public int Id { get { return id; } set { id = value; } } public string Name { get { return name; } set { name = value; } } } 2.操作U

工厂模式——抽象工厂模式(+反射)

这里又出现了一个抽象工厂模式,这个抽象工厂模式又是什么呢? 我们现在来模拟一个场景,现在用的是Mysql数据库,明天让你更换为Oracle数据库.此时,想想要做多少的改动.但我们如果用工厂模式,这会让你节省大量时间. 首先,我们用工厂方法模式来设计这个程序. 我们画出类的UML图. IFactory作为工厂类的接口,有两个子类,分别用来构造不同的实例. IFactory工厂接口代码如下: package day_3_facoryMethod_db; /** * 数据库工厂类 * @author

C++利用反射和简单工厂模式实现业务模块解耦

1. 业务说明 为了便于说明,举一个简单的例子.假设现在有一个项目需要建立一个和银行交互的平台,目前只接入工商银行,后续接入其他银行,每个银行的业务都有差异,报文格式可能也不一致. 这里只列举几个简要的流程,仅包括拼报文,发送报文,接收报文,解析报文,其余整体架构以及后续处理等内容省略. 2. 初步设计 创建一个银行交互类 BankOpt,包括四个函数: int setMsg(); //拼报文 int sendMsg(); //发送报文 int getMsg(); //接收报文 int pars

【iOS开发系列】用简单工厂模式理解OC反射机制

// 在iOS开发中,简单工厂模式使用得并不多.但是.我认为这是OC反射机制很好的一个例子, // 所以本文将以计算器为例,讲解简单工厂模式和OC的反射机制. // [简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类( // 这些产品类继承自一个父类或接口)的实例.该模式中包含的角色及其职责:工厂角色.抽 // 象产品角色.具体产品角色] // --百度百科 简单工厂模式 // 上面这句话可能不怎么好理解,我在网上找到了一个例子,可能例子本身不能完全解释这个 // 设