? 動(dòng)態(tài)代理
定義
代理:本來(lái)應(yīng)該自己做的事情艳悔,請(qǐng)了別人來(lái)做猜年,被請(qǐng)的人就是代理對(duì)象
動(dòng)態(tài)代理:在程序運(yùn)行過(guò)程中產(chǎn)生的這個(gè)對(duì)象乔外,而程序運(yùn)行過(guò)程中產(chǎn)生對(duì)象其實(shí)
就是我們剛才反射講解的內(nèi)容一罩,所以聂渊,動(dòng)態(tài)代理其實(shí)就是通過(guò)反射來(lái)生成一個(gè)代理對(duì)象汉嗽。
java中動(dòng)態(tài)代理的使用
在Java中java.lang.reflect包下提供了一個(gè)Proxy類和一個(gè) 接口,通過(guò)使用這個(gè)類和接口就可以生成動(dòng)態(tài)代理對(duì)象
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
最終會(huì)調(diào)用InvocationHandler的方法
InvocationHandler Object invoke(Object proxy,Method method,Object[] args)
演示
publicstaticvoidmain(String[]args)throwsException{
? ? Studentstudent=newStudent();
? ? //創(chuàng)建Student的代理對(duì)象
? ? MyInterfacep=(MyInterface)Proxy.newProxyInstance(Student.class.getClassLoader(),Student.class.getInterfaces(),newInvocationHandler() {
? ? ? ? @Override
? ? ? ? publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{
? ? ? ? ? ? System.out.println("你好");
? ? ? ? ? ? method.invoke(student);
? ? ? ? ? ? returnnull;
? ? ? ? }
? ? });
? ? p.method();
}
原理
利用對(duì)象的類的字節(jié)碼接口,寫(xiě)出一個(gè)新的類到本地區(qū),通過(guò)編譯器直接編譯成.class文件,再通過(guò)類加載器加載進(jìn)來(lái)
弊端: 代理的對(duì)象必須實(shí)現(xiàn)接口
cglib
定義
非java原生的動(dòng)態(tài)代理, 效率更高,限制更小
可以代理沒(méi)有接口的類
使用
導(dǎo)包
演示
publicstaticvoidmain(String[]args) {
? ? //導(dǎo)入包? cglib-core? asm? ? ant? ? ant-launcher
? ? //創(chuàng)建運(yùn)行器
? ? MethodInterceptormi=newMethodInterceptor() {
? ? ? ? @Override
? ? ? ? publicObjectintercept(Objectarg0,Methodarg1,Object[]arg2,MethodProxyarg3)throwsThrowable{
? ? ? ? ? ? System.out.println("運(yùn)行前");
? ? ? ? ? ? arg3.invokeSuper(arg0,arg2);
? ? ? ? ? ? System.out.println("運(yùn)行后");
? ? ? ? ? ? returnnull;
? ? ? ? }
? ? };
? ? //獲取代理類
? ? Enhancerenhancer=newEnhancer();
? ? //設(shè)置父類
? ? enhancer.setSuperclass(Demo.class);
? ? //運(yùn)行任務(wù)
? ? enhancer.setCallback(mi);
? ? //創(chuàng)建代理對(duì)象
? ? Demod=(Demo)enhancer.create();
? ? d.method();
}
總結(jié)
單例模式
模式: 針對(duì)某種問(wèn)題的最優(yōu)解
懶漢式, 餓漢式 , 餓漢式的變形體
如何寫(xiě)單例模式
私有化構(gòu)造方法
提供自己創(chuàng)建的對(duì)象給使用者
優(yōu)點(diǎn) :
節(jié)省內(nèi)存空間,? 提升訪問(wèn)的速度
缺點(diǎn) :
相對(duì)于靜態(tài)來(lái)說(shuō), 效率還是要低一些
枚舉
枚舉就是多例的簡(jiǎn)寫(xiě)形式
枚舉項(xiàng)的權(quán)限, 修飾符, 類型, new 省略
枚舉的注意事項(xiàng)
類加載
就是將.class文件從硬盤(pán)上讀取到內(nèi)存中,變成一個(gè)java可以使用的類
類加載器
四個(gè)類加載器和他們的應(yīng)用范圍
根類加載器不是java代碼寫(xiě)的
雙親委派模型
加載一個(gè)類的時(shí)候,從最底層的類加載器開(kāi)始逐層上傳, 一直到頂層, 整個(gè)過(guò)程要檢測(cè)這個(gè)類有沒(méi)有被加載過(guò)
作用 : 保持類的唯一性
反射
反射其實(shí)就是java提供的另外一種編程模式
提高了代碼的兼容性, 擴(kuò)展性
反射操作構(gòu)造方法, 操作成員變量, 操作成員方法
?default關(guān)鍵字
定義
1.8中允許我們給接口添加一個(gè)非抽象的方法實(shí)現(xiàn), 在方法使用default關(guān)鍵字就可以了,這個(gè)特征又叫做拓展方法
演示
publicinterfaceMyInterface{
? ? //使用default的關(guān)鍵字
? ? publicdefaultvoidmethod(){
? ? ? ? System.out.println("你好....");
? ? }
}
注意事項(xiàng)
我們都知道, java之所以支持多實(shí)現(xiàn)就是應(yīng)為接口中沒(méi)有具體的邏輯代碼, 不會(huì)造成沖突的問(wèn)題, 那么1.8之后我們可以在接口中編寫(xiě)具體的邏輯代碼了,那么多實(shí)現(xiàn)的時(shí)候會(huì)沖突嗎 ?
肯定會(huì)沖突的,所以為了解決這個(gè)問(wèn)題, 編譯器要求如果多實(shí)現(xiàn)的時(shí)候出現(xiàn)了相同名稱的非抽象方法的話,子類就必須重寫(xiě)這個(gè)方法
多實(shí)現(xiàn)
publicclassDemoimplementsMyInterface,MyInterface2{
?
? ? @Override
? ? publicvoidmethod() {
? ? ? ? System.out.println("子類必須重寫(xiě)多個(gè)接口中相同名稱的非抽象方法");
MyInterface.super.method();
? ? }
?
}
二. 接口中的靜態(tài)方法
定義
在接口中定義一個(gè)靜態(tài)的方法, 可以有具體的代碼實(shí)現(xiàn)
演示
publicinterfaceMyInterface{
? ? //靜態(tài)方法 只能接口自己使用
? ? //接口中的靜態(tài)方法權(quán)限必須是public的, 默認(rèn)加上public
? ? staticvoidmethod3(){
? ? ? ? System.out.println("我是接口中的靜態(tài)方法");
? ? }
}
注意事項(xiàng)
子類無(wú)法使用接口中的靜態(tài)方法
接口中的靜態(tài)方法的權(quán)限必須是公共的,可以不寫(xiě),默認(rèn)是公共的
lambda表達(dá)式
定義
一種簡(jiǎn)寫(xiě)形式,格式精簡(jiǎn), 很酷
每一個(gè)lambda的表達(dá)都對(duì)應(yīng)一個(gè)類型,通常是接口類型的
適用于函數(shù)式接口(只有一個(gè)抽象方法的接口)
格式
(參數(shù)...) -> {執(zhí)行代碼} 返回一個(gè)可用的對(duì)象
當(dāng)只有一句代碼時(shí),大括號(hào)可以省略, 建議省略
演示
publicstaticvoidmain(String[]args) {
? ? List<String>list=Arrays.asList("hh","dd","ni","kk");
? ? //之前的寫(xiě)法
? ? Collections.sort(list,newComparator<String>() {
? ? ? ? publicintcompare(Stringo1,Stringo2) {
? ? ? ? ? ? returno1.compareTo(o2);
? ? ? ? }
? ? });
? ? //lambda表達(dá)式的寫(xiě)法
? ? Collections.sort(list, (Stringa,Stringb)->{
? ? ? ? returna.compareTo(b);
? ? });
? ? System.out.println(list);
?
}
方法的引用
使用 : : 來(lái)引用一個(gè)類的方法
publicinterfaceDoing<K,T>{
? ? publicTdoing(Kk);
}
?
publicstaticvoidmain(String[]args) {
? ? //調(diào)用類中的靜態(tài)方法來(lái)處理接口中方法上的參數(shù)
? ? Doing<String,Integer>d=Integer::valueOf;
? ? Integerinteger=d.doing("123");
? ? System.out.println(integer);
}
publicstaticvoidmain(String[]args) {
? ? //調(diào)用對(duì)象的方法
? ? Doing<String,Integer>d="java"::lastIndexOf;
? ? Integeri=d.doing("v");
? ? System.out.println(i);
}
構(gòu)造方法的引用
用new關(guān)鍵字來(lái)代替構(gòu)造方法
publicclassPerson{
? ? Stringname;
?
? ? Person(Stringname) {
? ? ? ? super();
? ? ? ? this.name=name;
? ? }
?
? ? @Override
? ? publicStringtoString() {
? ? ? ? return"Person [name="+name+"]";
? ? }
?
}
publicstaticvoidmain(String[]args) {
? ? //引用對(duì)象的構(gòu)造方法
? ? Doing<String,Person>d=Person::new;
? ? Personperson=d.doing("小明");
? ? System.out.println(person);
}
注意事項(xiàng)
lambda表達(dá)式指向的接口必須和調(diào)用的方法的參數(shù)一致,也就是說(shuō)相當(dāng)于是接口實(shí)現(xiàn)類中的方法調(diào)用你指向的方法
lambda表達(dá)式中訪問(wèn)外層作用域和老版本的匿名對(duì)象的方式很相似, 你可以直接訪問(wèn)標(biāo)記了final的外層局部變量, 或者示例的字段以及靜態(tài)變量
lambda表達(dá)式中無(wú)法訪問(wèn)接口中的默認(rèn)方法(就是被default修飾的方法)
四. Stream接口
定義
表示能應(yīng)用在一組元素上一次執(zhí)行的操作序列
其實(shí)就是找了一個(gè)地方將執(zhí)行了某個(gè)方法后剩下的元素存放起來(lái)
提供了許多操作集合的方法,而且原集合數(shù)據(jù)不受影響
常用的方法
filter? ? 過(guò)濾
sorted? ? 排序
map? ? 轉(zhuǎn)化
match? 匹配
count? 計(jì)數(shù)
演示
publicstaticvoidmain(String[]args) {
? ? List<String>stringCollection=newArrayList<>();
? ? stringCollection.add("ddd2");
? ? stringCollection.add("aaa2");
? ? stringCollection.add("bbb1");
? ? stringCollection.add("aaa1");
? ? stringCollection.add("bbb3");
? ? stringCollection.add("ccc");
? ? stringCollection.add("bbb2");
? ? stringCollection.add("ddd1");
? ? //過(guò)濾出以a開(kāi)頭的元素并遍歷
? ? stringCollection.stream().
? ? filter((s)->s.startsWith("a"))
? ? .forEach(System.out::println);;
}
并行
并行Stream可以在多個(gè)線程上同時(shí)執(zhí)行
publicstaticvoidmain(String[]args) {
? ? intmax=1000000;
? ? List<String>values=newArrayList<>(max);
? ? for(inti=0;i<max;i++) {
? ? ? ? //創(chuàng)建隨機(jī)id
? ? UUIDuuid=UUID.randomUUID();
? ? values.add(uuid.toString());
? ? }
? ? longt1=System.nanoTime();
? ? //獲取并行的stream
? ? longcount=values.parallelStream().sorted().count();
? ? System.out.println(count);
? ? longt2=System.nanoTime();
? ? System.out.println(t2-t1);
}
五. Date
定義
java 8 在包java.time下包含了一組全新的時(shí)間日期API
ZoneId
定義時(shí)區(qū)
publicstaticvoidmain(String[]args) {
? ? System.out.println(ZoneId.getAvailableZoneIds());
? ? //獲取某個(gè)城市的時(shí)區(qū)
? ? ZoneIdzone1=ZoneId.of("Europe/Berlin");
? ? ZoneIdzone2=ZoneId.of("Asia/Shanghai");
? ? System.out.println(zone1.getRules());
? ? System.out.println(zone2.getRules());
}
LocalTime
一個(gè)沒(méi)有時(shí)區(qū)信息的時(shí)間,以設(shè)置的時(shí)區(qū)為準(zhǔn)備
publicstaticvoidmain(String[]args) {
? ? //獲取所有的時(shí)區(qū)信息
? ? System.out.println(ZoneId.getAvailableZoneIds());
? ? //獲取某個(gè)城市的時(shí)區(qū)
? ? ZoneIdzone1=ZoneId.of("Europe/Berlin");
? ? ZoneIdzone2=ZoneId.of("Asia/Shanghai");
? ? LocalTimenow1=LocalTime.now(zone1);
? ? LocalTimenow2=LocalTime.now(zone2);
? ? //判斷時(shí)間1以是否在時(shí)間2之前
? ? System.out.println(now1.isBefore(now2));// true
? ? //使用ChronoUnit計(jì)算兩個(gè)時(shí)間差值
? ? longhoursBetween=ChronoUnit.HOURS.between(now1,now2);
? ? longminutesBetween=ChronoUnit.MINUTES.between(now1,now2);
? ? System.out.println(hoursBetween);
? ? System.out.println(minutesBetween);
}
六.其他新特性
重復(fù)注解
可以將參數(shù)的名字保留到字節(jié)碼中
Nashorn引擎 : jjs , 可以執(zhí)行js代碼
移除了FermGen空間,用Metaspace代替
-XX:MetaSpaceSize與-XX:MaxMetaspaceSize被代替-XX:PermSize與-XX:MaxPermSize
一階段的知識(shí)點(diǎn)
了解計(jì)算機(jī)基礎(chǔ)知識(shí)
了解的dos命令
了解java的歷史
jdk的安裝和環(huán)境變量的配置
進(jìn)制
java的編譯-運(yùn)行方式
變量, 常量? 數(shù)據(jù)類型(基本的8個(gè),引用的5個(gè))
運(yùn)算符? :? 算數(shù)運(yùn)算符? 復(fù)制運(yùn)算符 關(guān)系運(yùn)算符? 邏輯運(yùn)算符(雙與雙或/單與單或)? 位運(yùn)算符(& | ~? >> <<? >>>)? ? 三元運(yùn)算符
判斷 循環(huán)
數(shù)組 (長(zhǎng)度固定) 二維數(shù)組
方法? (方法的組成, 重載: 方法名相同,參數(shù)列表不同)
面向?qū)ο?/p>
如何寫(xiě)一個(gè)類
如何使用一個(gè)類
類和類之間的關(guān)系(重寫(xiě))
抽象類和接口
多態(tài) : 提高擴(kuò)展性和兼容性
內(nèi)部類 :? 成員的, 靜態(tài)的, 局部的, 匿名的
異常 : 最重要的時(shí)類名
常用類
Object
String (方法必須記熟)
StringBuffer? StringBuilder
Math Date SimpleDateFormat
Random? BigInteger? BigDcimal
集合
Collection Map
List Set Queue
List :
ArrayList: 查改快 增刪慢? LInkedList: 增刪快, 查改慢
Set
HashSet : 去重? ? TreeSet : 去重 排序
Map (key不能重復(fù))
HashMap :? 快? ? TreeMap : 排序
Collections
迭代器? 迭代器運(yùn)行時(shí)不能改變?cè)?/p>
泛型 :
多線程
多線程的好處
多線程的創(chuàng)建使用
多線程的狀態(tài)
鎖
線程的通信
線程池
File 類
操作本地路徑(文件和文件夾)
遞歸
流
字節(jié)流 字符流?
文件流中, 除了FileInputStream和FileOutputStream之外, 其他的都是緩沖流
緩沖流有緩沖區(qū), 使用時(shí)要注意
網(wǎng)絡(luò)編程
ip 端口號(hào)
UDP TCP
java 兩種網(wǎng)絡(luò)編程方式(主要記TCP)
NIO
非阻塞? 模擬多線程, 沒(méi)有多線程的開(kāi)銷(xiāo), 實(shí)質(zhì)還是輪詢處理, 只適合小流量高并發(fā)的場(chǎng)景
通道管理器
單例 多例? 枚舉 類加載器? 反射? 多態(tài)代理? 注解? ?
1 . 8 新特性 :? ? 接口中 default static的使用? ? la