今日内容
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
}
}