JAVA11_29学习总结(反射,设计模式)

本文介绍了Java中的设计原则,如开闭原则,以及如何通过反射修改和访问类的成员变量。重点讲解了反射API的应用,包括赋值私有属性,以及使用JDK动态代理创建代理对象和行为定制。此外,还涵盖了单例模式和代理设计模式的实践案例。
摘要由CSDN通过智能技术生成

今日内容

1. 设计原则

设计原则
    开闭原则
        ---对修改关闭,对扩展开放!

2. refect 成员变量

反射给成员变量赋值
    1)获取当前类的字节码文件对象
    2)创建当前类实例
    3)通过字节码文件对象获取当前类的成员变量的Field类对象
        public Field getField(String name)
            ---获取公共的成员变量Field类对象--参数是属性名称
        public Field getDeclaredField(String name)
            ---获取指定的成员变量的Field类对象
    4)强制访问
    5)赋值
        public void set(Object obj,Object value)
            ---给成员变量的类对象Field赋值
                Object obj --当前类实例
                Object value --实际参数
//测试用类
public class Demo {
    private String name ;
    private int age ;
    public String sex ;
​
    public Demo() {
    }
​
    public Demo(String name, int age) {
        this.name = name;
        this.age = age;
    }
​
    @Override
    public String toString() {
        return "Demo{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                '}';
    }
}
​
​
​
import java.lang.reflect.Field;
​
public class Test {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        //获取当前类的字节码文件
        Class clazz = Class.forName("refect.refectTest_01.Demo");
        //创建当前类实例--如果是无参且无参内没有操作,可以简写
        Object obj = clazz.newInstance() ; //相当于创建了构造器,然后获取公共的构造方法
        //获取当前类的成员变量--公共成员变量
        Field field = clazz.getField("sex") ;
        //获取当前类的成员变量--所有包括私有
        Field field1 = clazz.getDeclaredField("name");
        Field field2 = clazz.getDeclaredField("age");
        //进行赋值
        field.set(obj,"男");
        //对于私有属性强制访问
        field1.setAccessible(true);
        field1.set(obj,"钟离");
        field2.setAccessible(true);
        field2.set(obj,500);
        //展示数据
        System.out.println(obj);//Demo{name='钟离', age=500, sex='男'}
    }
}

3. jdk动态代理

jdk动态代理
    使用jdk动态代理的前提是有一个接口
        Java.lang.refect.Proxy
            --提供了创建动态代理和实例的方法!
            public static Object newProxyInstance(
                ClassLoader loader --当前接口对象的类加载器
               ,Class<?>[] interfaces --代理实现接口列表字节码文件的数组
               ,InvocationHandler h --代理实例,调用处理程序实现的接口
               )

//定义主体方法
public interface UserDao {
    //添加
    void add();
    //删除
    void delete();
    //修改
    void set();
    //查询
    void select();
}



//真实角色,完成主体功能
public class UserDaoImple implements UserDao{
    @Override
    public void add() {
        System.out.println("添加了数据!");
    }

    @Override
    public void delete() {
        System.out.println("删除了数据!");
    }

    @Override
    public void set() {
        System.out.println("修改了数据!");
    }

    @Override
    public void select() {
        System.out.println("查询了数据!");
    }
}



import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
//代理角色,实现InvocationHandler接口,完成边角料操作!
public class MyHandler implements InvocationHandler {
    //定义---接收主体方法类对象
    private Object target ;
    public MyHandler(Object target){ //通过有参构造将主体方法类对象传递进去
        this.target = target ;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //进行所有主体方法之前要检查用户权限
        System.out.println("检查用户权限!");
        //进行主体方法调用--需要主体方法类对象--反射进行调用!method
        Object obj = method.invoke(target,args);//target是传入的主体方法类对象,args是具体参数
        //完成主体方法之后,进行日志记载
        System.out.println("记录用户操作!");
        return obj;
    }
}



import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

//测试类,完成测试
public class Test {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
        UserDaoImple udi = new UserDaoImple();
        //获取主体方法类字节码文件
        Class clazz = Class.forName("refect.refectTest_02.UserDaoImple");
        //获取真实类的类加载器Classloader
        ClassLoader loader = clazz.getClassLoader();
        //真实角色实现接口的字节码文件对象的数组
        Class[] interfaces = clazz.getInterfaces();
        //获取代理实例--创建代理类的对象
        InvocationHandler handler = new MyHandler(udi);//传入真实类对象
        //利用动态代理的静态方法--强转为真实类方法接口
        UserDao ud = (UserDao) Proxy.newProxyInstance(loader, interfaces, handler);
        ud.add();
        ud.set();
        ud.select();
        ud.delete();
    }
}

4. 设计模式

设计模式---是一种设计思想
    让代码结构更健壮!
        1)创建型设计模式---对象的创建 (使用比较多的)
            单例设计模式
            简单工厂--静态方法工厂模式,工厂方法模式
            构建者(Builder)..
        2)结构型设计模式---构造一个对象(行为,属性)----代理,装饰者,适配器...
            代理设计模式(Proxy)
            适配器模式(Adapter)
            桥接模式(Bridge)
            装饰者设计模式(Decorator)
        3)行为型设计模式
            将多个类或者对象相互协作,共同完成单个对类或者对象无法单独完成的任务!
            解释器
            模板方法模式
            观察者设计模式

单例设计模式
    内存中始终只有一个对象的模式!

饿汉式
    单例设计模式中最安全的一种设计模式!--不会出现线程安全问题!
    1)在类的成员位置提供静态实例变量
        --初始化过程中直接创建对象
       2)当前类一定是具体类,构造方法私有化
           --防止从外部进行实例化
    3)对外提供公共的静态方法,返回这个实例!(返回值就是当期类本身)
        --外部获得唯一的对象!

//私有构造方法
public class Demo {
    //类在初始化直接创建唯一对象
    private static Demo demo = new Demo();
    //构造方法私有化,无法从外部创建对象
    private Demo(){}
    //提供静态方法给外部获取唯一对象
    public static Demo getDemo(){
        return demo ;//返回值是该类的实例
    }
}



//测试类
public class Test {
    public static void main(String[] args) {
        //获得唯一对象--通过类名直接调用
        Demo demo = Demo.getDemo();
        Demo demo1 = Demo.getDemo();
        //比较两个值是否相同!
        System.out.println(demo==demo1);//true--相等,证明拿到的是同一个对象!唯一对象!
    }
}

懒汉式
    是可能出现安全问题的一种单例模式
    1)当前这个类构造方法私有化
    2)成员位置---提供了静态当前的类变量(此处只是声明了当前类型的一个变量)
    3)提供一个静态的成员方法,返回值是当前类本身(安全方法)
           场景:按需加载或者延迟加载,需要用的时候才去创建对象

//构造方法私有
public class Demo {
    //声明静态的变量但是不创建对象
    private static Demo demo ;//在有需要时创建
    //私有化构造方法,禁止外部直接创建对象
    private Demo(){}
    //提供外部调用的方法--不安全,如果有多个线程调用容易出问题,所以用synchronized!
    public static synchronized Demo getDemo(){
        if (demo==null){
            demo = new Demo();
        }
        return demo;
    }
}



public class Test {
    public static void main(String[] args) {
        //获取对象并比较
        Demo demo = Demo.getDemo() ;
        Demo demo1 = Demo.getDemo();
        System.out.println(demo==demo1);//true
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五目炒饭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值