Base64的加密和解密(jdk8新特性)(重点)

/*java.util.Base64该类仅由用于获得Base64编码方案的编码器和解码器的静态方法组成。作用:使用Base64里边的编码器对数据进行编码(加密)使用Base64里边的解码器对数据进行解码(解密)静态成员方法:static Base64.Encoder getEncoder​() 获取加密器static Base64.Decoder getDecoder​() 获取解密器java.util.Base64.Encoder:是Base64的内部类,用于对数据进行加密成员方法:String encodeToString​(byte[] src) 使用Base64编码方案将指定的字节数组编码为字符串。java.util.Base64.Decoder:是Base64的内部类,用于对数据进行解密成员方法:byte[] decode​(String src) 使用Base64编码方案将Base64编码的字符串解码为新分配的字节数组。*/
public class Demo01Base64 {public static void main(String[] args) {String s1 = "国家的绝密文件!";System.out.println("原字符串:"+s1);//原字符串:国家的绝密文件!//使用加密器Encoder中的方法encodeToString​把字符串进行加密String s2 = Base64.getEncoder().encodeToString(s1.getBytes());System.out.println("加密后的字符串:"+s2);//加密后的字符串:5Zu95a6255qE57ud5a+G5paH5Lu2IQ==//使用解密器Decoder中的方法decode把加密后的字符串进行解密byte[] bytes = Base64.getDecoder().decode(s2);String s3 = new String(bytes);System.out.println("解密后的字符串:"+s3);}
}

动态代理(原理)

动态代理概述

动态代理代码实现

Star接口

//培养明星的接口
public interface Star {//培养唱歌的方法public abstract void changge();//培养跳舞的方法public abstract void tiaowu();//培养演电影的方法public abstract String yandianying(int money);//培养吃饭的方法public abstract void chifan();//培养玩游戏的方法public abstract void wanyouxi();
}

Caixukun类

public class CaiXuKun implements Star {@Overridepublic void changge() {System.out.println("蔡徐坤在唱歌");}@Overridepublic void tiaowu() {System.out.println("蔡徐坤在跳舞+打篮球");}@Overridepublic String yandianying(int money) {System.out.println("蔡徐坤在演电影"+money);return "电影演完了";}@Overridepublic void chifan() {System.out.println("和蔡徐坤一起吃饭");}@Overridepublic void wanyouxi() {System.out.println("和蔡徐坤一起玩游戏");}
}

WuQian类

/*ctrl+r:查找并替换*/
public class WuQian implements Star {@Overridepublic void changge() {System.out.println("吴Q在唱歌");}@Overridepublic void tiaowu() {System.out.println("吴Q在跳舞");}@Overridepublic String yandianying(int money) {System.out.println("吴Q在演电影"+money);return "电影演完了";}@Overridepublic void chifan() {System.out.println("吴Q吃大锅饭");}@Overridepublic void wanyouxi() {System.out.println("吴Q踩缝纫机");}
}

InvocationHandler接口的实现类

/*java.lang.reflect.InvocationHandler接口InvocationHandler 是代理实例的调用处理程序 实现的接口。用来生产代理人对象的动态代理接口可以把被代理人(明星)传递到InvocationHandler接口的实现类中,让InvocationHandler接口的实现类生产明星的代理人InvocationHandler接口的方法Object invoke(Object proxy, Method method, Object[] args) 在代理实例上处理方法调用并返回结果。作用:使用invoke方法对被代理人(明星)的方法进行拦截,部分方法可以运行,部分方法不能运行参数:Object proxy:内部产生的代理人对象Method method:invoke会对明星的方法(changge,tiaowu..)进行拦截,使用反射技术获取到这些方法,把方法赋值给methodObject[] args:拦截到明星方法的参数返回值:Object:就是拦截到方法的返回值注意:在实现类中定义一个变量为Star类型使用带参数构造方法,传递Star接口的实现类对象(明星),在类的内部生产明星的代理人对象*/
public class InvocationHandlerImpl implements InvocationHandler {//在实现类中定义一个变量为Star类型private Star star;public InvocationHandlerImpl(Star star) {this.star = star;}/*invoke方法对被代理人(明星)的方法进行拦截,部分方法可以运行,部分方法不能运行调用明星changge,tiaowu,yandianying方法,可以运行调用明星chifan,wanyouxi的方法,拦截不运行*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//获取到方法名称String methodName = method.getName();//对方法名称进行判断if("chifan".equals(methodName)){throw new RuntimeException("不和你吃饭!");}if("wanyouxi".equals(methodName)){throw new RuntimeException("不和玩游戏!");}//其他的方法,使用Method类的方法invoke让方法运行Object v = method.invoke(star, args);return v;}
}

测试类:

/*动态代理:创建代理人对象,对明星进行代理,对明星的方法进行拦截调用明星changge,tiaowu,yandianying方法,可以运行调用明星chifan,wanyouxi的方法,拦截不运行想要实现动态代理:使用Proxy类生产代理人对象java.lang.reflect.Proxy:Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。Proxy类中的静态方法:可以生产代理人对象static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。参数:ClassLoader loader:传递类加载器Class<?>[] interfaces:传递被代理人实现的所有接口InvocationHandler h:生产代理人的接口,传递InvocationHandler接口的实现类对象返回值:Object:返回的就是代理人对象*/
public class Demo01Proxy {public static void main(String[] args) {//没有使用动态代理CaiXuKun cxk = new CaiXuKun();//cxk.changge();//cxk.tiaowu();//获取蔡徐坤的代理人对象Star cxkProxy = (Star) Proxy.newProxyInstance(CaiXuKun.class.getClassLoader(),CaiXuKun.class.getInterfaces(),new InvocationHandlerImpl(cxk));cxkProxy.changge();cxkProxy.tiaowu();String s = cxkProxy.yandianying(100);System.out.println(s);//cxkProxy.chifan();//cxkProxy.wanyouxi();//获取吴Q的代理人对象Star wqProxy = (Star)Proxy.newProxyInstance(WuQian.class.getClassLoader(),WuQian.class.getInterfaces(),new InvocationHandlerImpl(new WuQian()));wqProxy.changge();wqProxy.tiaowu();wqProxy.chifan();}
}

动态代理综合案例

需求:
模拟Collections的unmodifiableList方法,对List接口进行代理
调用List接口的方法会被拦截
如果使用的size,get方法,没有对集合进行修改,则允许执行
如果使用的add,remove,set方法,对集合进行了修改,则抛出运行时异常

分析:
1.定义一个代理方法proxyList
参数:传递List集合
返回值:被代理之后的List集合
2.方法内部可以使用Proxy类中的方法实现动态代理

代码实现:

/*需求:模拟unmodifiableList方法,对List接口进行代理调用List接口的方法会被拦截如果使用的size,get方法,没有对集合进行修改,则允许执行如果使用的add,remove,set方法,对集合进行了修改,则抛出运行时异常分析:1.定义一个代理方法proxyList参数:传递List集合返回值:被代理之后的List集合2.方法内部可以使用Proxy类中的方法实现动态代理*/
public class Demo02Proxy {public static void main(String[] args) {//创建List对象List<String> list = new ArrayList<>();list.add("a");list.add("b");list.add("c");//调用proxyList方法,获取List接口的代理人对象List<String> listProxy = proxyList(list);System.out.println(listProxy.size());//3System.out.println(listProxy.get(1));//blistProxy.remove(0);//UnsupportedOperationException: remove no run}//1.定义一个代理方法proxyListpublic static List<String> proxyList(List<String> list){//2.方法内部可以使用Proxy类中的方法实现动态代理List<String> listProxy = (List<String>)Proxy.newProxyInstance(Demo02Proxy.class.getClassLoader(),list.getClass().getInterfaces(),new InvocationHandlerImpl(list));return listProxy;}
}
public class InvocationHandlerImpl implements InvocationHandler {//定义一个List集合的变量private List<String> list;public InvocationHandlerImpl(List<String> list) {this.list = list;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//invoke方法会获取list集合中的方法,在invoke方法内部对list集合的方法进行拦截//获取方法的名称String methodName = method.getName();//如果使用的add,remove,set方法,对集合进行了修改,则抛出运行时异常if("add".equals(methodName)){throw new UnsupportedOperationException("add no run");}if("remove".equals(methodName)){throw new UnsupportedOperationException("remove no run");}if("set".equals(methodName)){throw new UnsupportedOperationException("set no run");}//如果使用的size,get方法,没有对集合进行修改,则允许执行Object v = method.invoke(list, args);return v;}
}

动态代理案例流程图

总结

动态代理非常的灵活,可以为任意的接口实现类对象做代理

动态代理可以为被代理对象的所有接口的所有方法做代理,动态代理可以在不改变方法源码的情况下,实现对方法功能的增强,

动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。
动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。

动态代理同时也提高了开发效率。

缺点:只能针对接口的实现类做代理对象,普通类是不能做代理对象的。

正则表达式(重点)

正则表达式的概念及演示

/*正则表达式:就是一个包含某些规则的字符串用来对其他的字符串进行校验,校验其他的字符串是否满足正则表达式的规则需求:对QQ号进行校验1.长度5-15位2.全是数字3.第一位不是0校验QQ号的正则表达式"[1-9][0-9]{4,14}"学习目标:能看懂一般的正则表达式即可*/
public class Demo01Regex {public static void main(String[] args) {//获取一个用户输入的QQ号System.out.println("请输入一个QQ号:");String qq = new Scanner(System.in).nextLine();boolean b1 = checkQQ(qq);System.out.println("b1:"+b1);boolean b2 = checkQQRegex(qq);System.out.println("b2:"+b2);}//定义校验QQ号的方法,不使用正则表达式public static boolean checkQQ(String qq){//1.长度5-15位if(qq.length()<5 || qq.length()>15){return false;}//2.全是数字char[] chars = qq.toCharArray();for (char c : chars) {//判断字符是否在'0'到'9'之间if(c<'0' || c>'9'){return false;}}//3.第一位不是是0if("0".equals(qq.charAt(0)+"")){return false;}//满足所有的规则return true;}/*定义校验QQ号的方法,使用正则表达式String类中的方法:boolean matches(String regex) 告知此字符串是否匹配给定的正则表达式。判断字符串是否满足正则表达式的规则满足:返回true不满足:返回false*/public static boolean checkQQRegex(String qq){return qq.matches("[1-9][0-9]{4,14}");}
}

正则表达式-字符类

/*java.util.regex.Pattern:正则表达式的编译表示形式。正则表达式-字符类:[]表示一个区间,范围可以自己定义语法示例:1. [abc]:代表a或者b,或者c字符中的一个。2. [^abc]:代表除a,b,c以外的任何字符。3. [a-z]:代表a-z的所有小写字符中的一个。4. [A-Z]:代表A-Z的所有大写字符中的一个。5. [0-9]:代表0-9之间的某一个数字字符。6. [a-zA-Z0-9]:代表a-z或者A-Z或者0-9之间的任意一个字符。7. [a-dm-p]:a 到 d 或 m 到 p之间的任意一个字符*/
public class Demo02Regex {public static void main(String[] args) {String str = "ead";//false//1.验证str是否以h开头,以d结尾,中间是a,e,i,o,u中某个字符String regex = "h[aeiou]d";str = "hid";//truestr = "Hud";//falseboolean b1 = str.matches(regex);System.out.println("b1:"+b1);//2.验证str是否以h开头,以d结尾,中间不是a,e,i,o,u中的某个字符regex = "h[^aeiou]d";str = "h1d";//truestr = "had";//falseboolean b2 = str.matches(regex);System.out.println("b2:"+b2);//3.验证str是否a-z的任何一个小写字符开头,后跟adregex = "[a-z]ad";str = "wad";//truestr = "1ad";//falseboolean b3 = str.matches(regex);System.out.println("b3:"+b3);//4.验证str是否以a-d或者m-p之间某个字符开头,后跟adregex = "[a-dm-p]ad";str = "cad";//truestr = "ead";//falseboolean b4 = str.matches(regex);System.out.println("b4:"+b4);}
}

正则表达式-逻辑运算符

/*正则表达式-逻辑运算符语法示例:1. &&:并且2. | :或者*/
public class Demo03Regex {public static void main(String[] args) {String str = "had";//truestr = "ead";//falsestr = "Had";//false//1.要求字符串是小写[a-z]和福音字符[^aeiou]开头,后跟adString regex = "[[a-z]&&[^aeiou]]ad";boolean b1 = str.matches(regex);System.out.println("b1:"+b1);//2.要求字符串是aeiou中的某个字符开头,后跟adregex = "[a||e||i||o||u]ad";//"[a|e|i|o|u]ad"就相当于"[aeiou]" 或运算符是可以省略不写的str = "aad";//truestr = "1ad";//falseboolean b2 = str.matches(regex);System.out.println("b2:"+ b2);}
}

正则表达式-预定义字符

/*正则表达式-预定义字符语法示例:1. "." : 匹配任何字符。(重点)2. "\\d":任何数字[0-9]的简写;(重点)3. "\\D":任何非数字[^0-9]的简写;4. "\\s": 空白字符:[ \t\n\x0B\f\r] 的简写5. "\\S": 非空白字符:[^\s] 的简写6. "\\w":单词字符:[a-zA-Z_0-9]的简写(重点)7. "\\W":非单词字符:[^\w]注意:\本身就是转义字符,写正则表达式语法的时候,必须写\\,把有特殊含义的\转义为一个普通的\使用*/
public class Demo04Regex {public static void main(String[] args) {//1.验证str是否3位数字String str = "250";//truestr = "25a";//falseString regex = "[0-9][0-9][0-9]";regex = "\\d\\d\\d";boolean b1 = str.matches(regex);System.out.println("b1:"+b1);//2.验证手机号:1开头,第二位:3/5/8,剩下9位都是0-9的数字regex = "1[358]\\d\\d\\d\\d\\d\\d\\d\\d\\d";str = "13800138000";//truestr = "23800138000";//falsestr = "138001380001";//falsestr = "13800138a00";//falseboolean b2 = str.matches(regex);System.out.println("b2:"+b2);//3.验证字符串是否以h开头,以d结尾,中间是任何字符regex = "h.d";str = "h&d";//truestr = "h中d";//truestr = "1Ad";//falseboolean b3 = str.matches(regex);System.out.println("b3:"+b3);//4.验证str是否是:had.//注意: .不是任意字符,就是一个普通的.需要使用转义字符把有特殊含义的.转换为普通的.regex = "had\\.";str = "hadA";//falsestr = "had.";//trueboolean b4 = str.matches(regex);System.out.println("b4:"+b4);}
}

正则表达式-数量词

/*正则表达式-数量词语法示例:1. X? : 0次或1次2. X* : 0次到多次 任意次3. X+ : 1次或多次 X>=1次4. X{n} : 恰好n次 X=n次5. X{n,} : 至少n次 X>=n次6. X{n,m}: n到m次(n和m都是包含的)   n=<X<=m*/
public class Demo05Regex {public static void main(String[] args) {String str = "";//falsestr = "123";//truestr = "1234";//false//1.验证str是否是三位数字String regex = "\\d{3}";boolean b1 = str.matches(regex);System.out.println("b1:"+b1);//2.验证str是否是多位数字:1次以上的数字regex = "\\d+";str = "12312413221312";//truestr = "1";//truestr = "";//falsestr = "111a";//falseboolean b2 = str.matches(regex);System.out.println("b2:"+b2);//3.验证str是否是手机号:1开头,第二位:3/5/8,剩下9位都是0-9的数字regex = "1[358]\\d{9}";str = "13800138000";//truestr = "1380013800a0";//falseboolean b3 = str.matches(regex);System.out.println("b3:"+b3);//4.验证小数:必须出现小数点,但是只能出现1次double d =1.1;d = 0.1;d = .1;d = 1.;//d = .;System.out.println(d);regex = "\\d*\\.\\d+";str = "1.1";//truestr = ".1";//truestr = "1.";//truestr = "aa.1";str = "1.1.1";boolean b4 = str.matches(regex);System.out.println("b4:"+b4);//5.验证小数:小数点可以不出现,也可以出现1次regex = "\\d*\\.?\\d*";str = "10000";//truestr = "10000.13213123";//truestr = ".1212312";//truestr = "";//truestr = "a";//falsestr = "a";//falsestr = "11..11";//falseboolean b5 = str.matches(regex);System.out.println("b5:"+b5);//6.验证小数:要求匹配:3、3.、3.14、+3.14、-3.regex = "[+-]?\\d+\\.?\\d*";str = "3";//truestr = "3.";//truestr = "3.14";//truestr = "+3.14";//truestr = "-3.";//trueboolean b6 = str.matches(regex);System.out.println("b6:"+b6);//7.验证qq号码:1).5--15位;2).全部是数字;3).第一位不是0regex = "[1-9]\\d{4,14}";str = "11111";//truestr = "111";//falsestr = "111111a";//falseboolean b7 = str.matches(regex);System.out.println("b7:"+b7);}
}

正则表达式-分组括号()

/*正则表达式-分组括号( )*/
public class Demo06Regex {public static void main(String[] args) {String str = "abc";//truestr = "";//truestr = "abcabc";//truestr = "abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc";//truestr = "abcaaabbbccc";//false//校验字符串"abc"可以出现任意次String regex = "(abc)*";boolean b1 = str.matches(regex);System.out.println("b1:"+b1);str = "DG8FV-B9TKY-FRT9J-99899-XPQ4G";//b2:truestr = "DG8FV-B9TKY-FRT9J-99899-XPQ4G-";//b2:false//验证这个序列号:分为5组,每组之间使用-隔开,每组由5位A-Z或者0-9的字符组成regex = "([A-Z0-9]{5}-){4}[A-Z0-9]{5}";boolean b2 = str.matches(regex);System.out.println("b2:"+b2);}
}

String类中和正则表达式相关的方法

/*String类中和正则表达式相关的方法boolean matches(String regex) 判断字符串是否匹配给定的正则表达式。String[] split(String regex) 根据给定正则表达式的匹配拆分此字符串。String replaceAll(String regex, String replacement)把满足正则表达式的字符串,替换为新的字符串*/
public class Demo07Regex {public static void main(String[] args) {show04();}/*String[] split(String regex) 根据给定正则表达式的匹配拆分此字符串。*/private static void show01() {String s = "11-22-33-44-55";String[] arr = s.split("-");for (String str : arr) {System.out.println(str);}}//正则表达式中.代表任意字符串private static void show02() {String s = "192.168.1.100";String[] arr = s.split("\\.");System.out.println(arr.length);for (String str : arr) {System.out.println(str);}}private static void show03() {String s = "192 168 1 100";s = "192       168       1         100";String[] arr = s.split(" +");//根据一个空格或者多个连续的空格切割字符串System.out.println(arr.length);for (String str : arr) {System.out.println(str);}}/*String replaceAll(String regex, String replacement)把满足正则表达式的字符串,替换为新的字符串*/public static void show04(){String s = "12312asfdsa12123asa11c1fzvs1v*&&3242fsfa11";System.out.println("原字符串:"+s);//需求:使用replaceAll方法把字符串中每一个数字替换为@_@String reg = "\\d";String s1 = s.replaceAll(reg, "@_@");System.out.println("替换后的字符串:"+s1);//需求:使用replaceAll方法把字符串中的连续的数字替换为@_@reg = "\\d+";String s2 = s.replaceAll(reg,"@_@");System.out.println("替换后的字符串:"+s2);}
}

单例设计模式(重点)

饿汉式

/*单例:只能创建一个本类的对象单例设计模式:饿汉式人非常饥饿,直接把对象吃了无论是否有人使用类,都先创建好本类的对象,供用户使用实现步骤:1.私有空参数构造方法,不让用户直接创建对象2.定义一个私有的静态的Person变量,并进行初始化赋值3.定义一个公共的静态方法,返回Person对象*/
public class Person {//1.私有空参数构造方法,不让用户直接创建对象private Person(){}//2.定义一个私有的静态的Person变量,并进行初始化赋值private static Person p = new Person();//3.定义一个公共的静态方法,返回Person对象public static Person getInstance(){return p;}
}public class Demo01Singleton {public static void main(String[] args) {//正常情况下,可以根据类创建多个对象//Person p1 = new Person();//System.out.println(p1);//Person p2 = new Person();//System.out.println(p2);//Person p3 = new Person();//Person p4 = new Person();//Person p5 = new Person();//测试单例设计模式,无论调用多少次静态的方法,获取的对象都是同一个for (int i = 0; i < 20; i++) {Person p = Person.getInstance();System.out.println(p);}}
}

懒汉式

/*单例设计模式:懒汉式人非常懒,抽一鞭子动一下当我们要使用对象的时候,再创建对象实现步骤:1.私有空参数构造方法,不让用户直接创建对象2.在类中定义一个私有的静态的Person变量,不进行初始化赋值3.定义一个公共的静态的成员方法,返回Person对象,保证无论调用多少次方法,只返回一个对象*/
public class Person {//1.私有空参数构造方法,不让用户直接创建对象private Person(){}//2.在类中定义一个私有的静态的Person变量,不进行初始化赋值private static Person p;//3.定义一个公共的静态的成员方法,返回Person对象,保证无论调用多少次方法,只返回一个对象public static Person getInstance(){//增加一个判断,判断变量p的值是否为null(第一次调用方法),创建对象if(p == null){p = new Person();}//变量p不是null直接返回return p;}
}

解决懒汉式多线程问题

public class Demo01Sigleton {public static void main(String[] args) {//创建两个线程,每个线程获取20次对象new Thread(()->{for (int i = 0; i < 20; i++) {Person p = Person.getInstance();System.out.println(p);}}).start();new Thread(()->{for (int i = 0; i < 20; i++) {Person p = Person.getInstance();System.out.println(p);}}).start();}
}

执行结果

com.llz.demo07Sigleton.Person@2f404fd1
com.llz.demo07Sigleton.Person@67c084e1
com.llz.demo07Sigleton.Person@67c084e1
com.llz.demo07Sigleton.Person@67c084e1


解决方法如下

/*单例设计模式:懒汉式人非常懒,抽一鞭子动一下当我们要会使用对象的时候,在创建对象实现步骤:1.私有空参数构造方法,不让用户直接创建对象2.在类中定义一个私有的静态的Person变量,不进行初始化赋值3.定义一个公共的静态的成员方法,返回Person对象,保证无论调用多少次方法,只返回一个对象*/
public class Person {//1.私有空参数构造方法,不让用户直接创建对象private Person(){}//2.在类中定义一个私有的静态的Person变量,不进行初始化赋值private static Person p;//3.定义一个公共的静态的成员方法,返回Person对象,保证无论调用多少次方法,只返回一个对象public static Person getInstance(){//在外层在增加一个判断,可以提高程序的效率if(p==null){synchronized (Person.class){//增加一个判断,判断变量p的值是否为null(第一次调用方法),创建对象if(p == null){p = new Person();}}}//变量p不是null直接返回return p;}
}

小结
单例模式可以保证系统中一个类只有一个对象实例。

实现单例模式的步骤:

  1. 将构造方法私有化,使其不能在类的外部通过new关键字实例化该类对象。
  2. 在该类内部产生一个唯一的实例化对象,并且将其封装为private static类型的成员变量。
  3. 定义一个静态方法返回这个唯一对象。

多例设计模式(重点)

多例模式,是一种常用的软件设计模式。通过多例模式可以保证系统中,应用该模式的类有固定数量的实例。多例类要自我创建并管理自己的实例,还要向外界提供获取本类实例的方法。

例如:

​ 扑克牌程序,一个“扑克类”会创建固定的54个对象,不能多、也不能少。

​ 麻将程序,一个“骰子类”会创建固定的2个对象,不能多、也不能少。

​ 程序中需要用到“颜色的表示”,只能有三种颜色“红、绿、蓝”,一个“颜色类(Color)”应该只创建三个对象,来代 表这三个颜色。

多例模式的作用:使某个类,在程序运行期间,只能产生固定的几个对象,不能多、也不能少。
获取多个通用的对象

/*多例设计模式:获取多个通用的对象需求:只让程序产生3个Student对象,不能多,也不能少实现步骤:1.私有空参数构造方法,不让用户直接创建对象2.定义一个私有的,静态的,最终的变量,值定义对象的总个数3.定义一个自由的,静态的集合,存储多个对象4.定义一个静态代码块,产生3个对象,存储到集合中5.定义一个公共的静态的方法,给用户随机在集合中取出一个对象返回*/
public class Student {//1.私有空参数构造方法,不让用户直接创建对象private Student(){}//2.定义一个私有的,静态的,最终的变量,值定义对象的总个数private static final int MAX = 3;//3.定义一个自由的,静态的集合,存储多个对象private static ArrayList<Student> list = new ArrayList<>();//4.定义一个静态代码块,产生3个对象,存储到集合中static {for (int i = 0; i < MAX; i++) {list.add(new Student());}}//5.定义一个公共的静态的方法,给用户随机在集合中取出一个对象返回public static Student getInstance(){//定义一个Random对象Random r = new Random();//在集合索引的范围内,随机产生一个随机数int index = r.nextInt(list.size());//[0,1,2]//通过产生的随机索引,在集合中获取Student对象返回return list.get(index);}
}

小结
多例模式可以保证系统中一个类有固定个数的实例, 在实现需求的基础上, 能够提高实例的复用性.

实现多例模式的步骤:

  1. 创建一个类, 将构造方法私有化,使其不能在类的外部通过new关键字实例化该类对象。
  2. 在类中定义该类被创建的总数量
  3. 在类中定义存放类实例的list集合
  4. 在类中提供静态代码块,在静态代码块中创建类的实例
  5. 提供获取类实例的静态方法

枚举(重点)

/*枚举:它就是"多例设计模式:获取多个特定对象"的一种简单写法需求:获取两个Sex对象,一个代表男,一个代表女使用多例实现:public static final Sex MAN = new Sex("男");public static final Sex WOMAN = new Sex("女");使用枚举实现:MAN==>public static final Sex MAN = new Sex();WOMAN==> public static final Sex WOMAN = new Sex();枚举中也可以包含成员变量,成员方法,构造方法(私有),这3个必须写在枚举常量的下边*/
public enum Sex {MAN("男"),WOMAN("女");private String s;private Sex(String s) {this.s = s;}//重写toString方法,返回对象中的字符串@Overridepublic String toString() {return s;}
}
public class Demo01Enum {public static void main(String[] args) {//创建Student对象Student s = new Student();s.setName("柳岩");s.setAge(18);s.setSex(Sex.WOMAN);System.out.println(s);}
}

枚举的应用

枚举的作用:枚举通常可以用于做信息的分类,如性别,方向,季度等。

枚举表示性别:

public enum Sex {MAIL, FEMAIL;
}

枚举表示方向:

public enum Orientation {UP, RIGHT, DOWN, LEFT;
}

枚举表示季度

public enum Season {SPRING, SUMMER, AUTUMN, WINTER;
}

小结*

  • 枚举类在第一行罗列若干个枚举对象。(多例)
  • 第一行都是常量,存储的是枚举类的对象。
  • 枚举是不能在外部创建对象的,枚举的构造器默认是私有的。
  • 枚举通常用于做信息的标志和分类。

工厂设计模式(重点)

简单工厂设计模式

public class Dog extends Animal {@Overridepublic void eat() {System.out.println("狗吃肉!");}
}/*定义一个生产动物的工厂只生产动物,不生产其他对象定义一个静态方法,根据用户传递的动物名称,创建指定的动物返回*/
public class AnimalFactory {//定义一个静态方法,参数传递动物的名称,根据名称创建指定的动物返回public static Animal getInstance(String name){if("cat".equals(name)){return new Cat();}else if("dog".equals(name)){return new Dog();}else{//不是动物return null;}}
}/*简单工厂设计模式:创建一个工厂类,在工厂类中定义一个生产对象的方法我们要使用对象,不在自己创建对象了,使用工厂类的方法获取好处:可以传递不同的动物名称,产生不同的动物对象;解除耦合性,增强扩展性弊端:胡乱指示一个动物的名称,不存在,会抛出空指针异常解决:可以使用工厂方法设计模式来解决,产生多个工厂,每个工厂生产特定的动物对象*/
public class Demo01SimpleFactory {public static void main(String[] args) {//使用工厂类的方法,获取指定的动物对象//获取一个Cat对象Animal cat = AnimalFactory.getInstance("cat");cat.eat();//获取一个Dog对象Animal dog = AnimalFactory.getInstance("dog");dog.eat();//胡乱指示一个动物的名称Animal car = AnimalFactory.getInstance("car");car.eat();// null.eat(); NullPointerException:抛出了空指针异常}
}

工厂方法设计模式

/*工厂方法设计模式:可以设计多个工厂,每个工厂生产不同的对象猫工厂只生产猫,狗工厂只生产狗好处:可以解决简单工厂设计模式的弊端,不让用户传递参数弊端:如果动物过多,产生多个工厂*/
public class Demo01FactoryMethod {public static void main(String[] args) {//创建生产猫的工厂==>生产猫CatFactory catFactory = new CatFactory();Animal cat = catFactory.getInstance();cat.eat();//创建生产狗的工厂 ==>生产狗DogFactory dogFactory = new DogFactory();Animal dog = dogFactory.getInstance();dog.eat();}
}/*定义一个工厂的接口:所有的工厂都得实现这个接口*/
public interface Factory {//定义一个抽象的生产动物的方法public abstract Animal getInstance();
}/*生产猫的工厂,实现工厂接口只生产猫对象*/
public class CatFactory implements Factory{@Overridepublic Animal getInstance() {return new Cat();}
}/*定义生产狗的工厂,实现工厂接口只生产狗对象*/
public class DogFactory implements Factory{@Overridepublic Animal getInstance() {return new Dog();}
}

Base64j加密解密、动态代理、正则表达式、单例多例设计模式、枚举、工厂设计模式相关推荐

  1. 动态代理原理源码分析

    看了这篇文章非常不错转载:https://www.jianshu.com/p/4e14dd223897 Java设计模式(14)----------动态代理原理源码分析 上篇文章<Java设计模 ...

  2. 【学习笔记】结合代码理解设计模式 —— 代理模式(静态代理、动态代理、延伸)

    文章目录 什么是代理模式 一. 代理模式简介 二. 静态代理模式 三. 动态代理模式 万能模版 前言:笔记基于狂神设计模式视频.<大话设计模式>观后而写 (最近一直在更新之前的刷题博客,今 ...

  3. 面试官:什么是静态代理?什么是动态代理?注解、反射你会吗?

    前言 开场 一位穿着蓝色衬衫,牛仔裤,拿着一个白色保温杯的中年男子急匆匆地坐在你对面,看样子是项目上的东西很急,估摸面试时间不会太长,这样一想心情放松了许多-(后来我就被打脸了) ​ ​ 面试开始 面 ...

  4. 多态Class对象注册工厂反射动态代理

    运行时类型信息 类型信息(多态&Class对象&注册工厂&反射&动态代理) 一.为什么需要RTTI 二.Class对象 2.1 类字面常量 2.2 泛化的Class引用 ...

  5. week_06_动态代理,工厂方法,单例,File,IO,网络编程,反射,数据库语句

    动态代理 动态代理核心思想: 再程序执行过程中通过一些特殊的方式产生代理 jdk动态代理: 前提必须有一个接口 java.lang.reflect.Proxy:提供了创建动态代理类和实例的静态方法 p ...

  6. 【加密解密】单表加密(Javascript实现)

    2019独角兽企业重金招聘Python工程师标准>>> ■单表加密(monoalphabetic) 替换加密是密码学中按规律将文字加密的一种方式.替换加密中可以用不同字母数为一单元, ...

  7. 【Android 安全】DEX 加密 ( Java 工具开发 | 加密解密算法 API | 编译代理 Application 依赖库 | 解压依赖库 aar 文件 )

    文章目录 一.加密解密算法 API 二.编译代理 Application 依赖库 三.解压代理 Application 依赖库 aar 文件 参考博客 : [Android 安全]DEX 加密 ( 常 ...

  8. 【例26图片的加密解密操作】

    例26:图片的加密解密操作 //图片的加密----@Testpublic void test(){FileInputStream fis= null;FileOutputStream fos= nul ...

  9. php动态密码和加密解密函数的使用(动态密码、Discuz核心函数AuthCode、任意输入密码验证)

    php加密解密的使用 一.项目说明 二.项目分析 1.js外部文件 2.HTML容器构建 3.layui前端验证 4.php后端验证 封装函数 密码验证规则 strpos内置函数 三.经典的核心加密函 ...

最新文章

  1. Android 进程常驻(使用第三方MarsDaemon)(虽然不可用,但是还是保留下。)
  2. go爬取json_Python爬取百度文库学习
  3. 前端学习(2512):组件注册
  4. vue computed使用_vue computed正确使用方式
  5. python前端代码_python前端HTML
  6. android rxjava2 简书,RXJava2学习
  7. Websocket——原理及基本属性和方法
  8. 极乐技术周报(第十六期)
  9. rdd分组聚合算子xxByKey,xxBy
  10. Mac 上使用 zmodem 发送和接收堡垒机文件
  11. webrtc---桌面共享原理
  12. QT项目--简易音乐播放器
  13. 电脑测网速c语言,C层实现多线程测网速
  14. 统计学知识:相关系数
  15. 树莓派3B+ wifi 5G连接
  16. daytime协议的服务器和客户端程序,用socket套接字实现daytime协议的服务器和客户端程序精编版.doc...
  17. 在浏览器中嵌入播放器
  18. MongoDB分片实战
  19. mmsegmentation导出onnx模型的问题
  20. AutoHotKey的那些事儿:(一)、AutoHotkey常用命令

热门文章

  1. Android解决Unity游戏从后台返回黑屏问题
  2. 用计算机撩人套路,各种撩人的套路句子 经典的撩人套路大全
  3. proxyTable配置
  4. 深入比较手机网游与PC网游
  5. 微信如何导出微信联系人?微信导出所有好友微信号
  6. python切片冒号的用法
  7. python爬取喜马拉雅FM雪中悍刀行整本有声小说!下次教你们爬付费!
  8. 说说标签算法在视频推荐的那些事儿
  9. CAD绘图控件VectorDraw web library (javascript) v7.7010.1.0版本更新
  10. 腐烂国度2计算机学教科书怎么使用,腐烂国度2基本操作介绍_新手入门攻略详解_可可网...