天天看點

青春有你-Java基礎篇(2.5)

Java基礎篇(2.5)

    • 2、Java基礎知識
      • → 泛型
        • 泛型與繼承、類型擦除、泛型中 KTVE ? object 等的含義、泛型各種用法
        • List< Object> 、 List<?> 和原始類型 List 之間的差別?
      • → 反射
        • 反射與工廠模式、反射的作用
        • Class 類、java.lang.reflect.*
      • → 注解
        • 元注解、自定義注解、注解與反射的結合
      • → 序列化
        • 什麼是序列化與反序列化、為什麼序列化、序列化底層原理、序列化與單例模式、protobuf、為什麼說序列化并不安全
      • → 正規表達式
        • java.lang.util.regex.*
      • → 常用的 Java 工具庫
        • commons.lang3、commons.*...、 guava-libraries、 netty

2、Java基礎知識

→ 泛型

泛型與繼承、類型擦除、泛型中 KTVE ? object 等的含義、泛型各種用法

泛型與繼承:泛型是參數化類型,把運作時期可能産生的問題,提前到了編譯時期,用來保證代碼安全性。父類為泛型,子類繼承時:範圍大于或等于。

類型擦除: Java的泛型基本上都是在編譯器這個層次上實作的,在生成的位元組碼中是不包含泛型中的類型資訊的,使用泛型的時候加上類型參數,在編譯器編譯的時候會去掉,這個過程成為類型擦除。 如在代碼中定義List< Object>和List< String>等類型,在編譯後都會變成List,JVM看到的隻是List,而由泛型附加的類型資訊對JVM是看不到的。

常見的類型參數:

  1. T 代表一般的任何類。
  2. E 代表 Element 的意思,或者 Exception 異常的意思。
  3. K 代表 Key 的意思。
  4. V 代表 Value 的意思,通常與 K 一起配合使用。
  5. ?通配符, 代表某種确定的類型,但是又有不确定性。 比如<? extends Collection> 不确定類型,确定實作了Collection接口。能确定上限,或确定下限。
  6. object:超類,需要強制類型轉換,編譯時可能類型不一緻導緻報錯。

泛型的用法:泛型類、泛型接口、泛型方法

【參考連結】https://blog.csdn.net/briblue/article/details/76736356

限定通配符和非限定通配符、上下界限定符 extends 和 super

通配符有 3 種形式。

  1. <?>被稱作無限定的通配符。
  2. <? extends T>被稱作有上限的通配符。
  3. <? super T>被稱作有下限的通配符。

List< Object> 、 List<?> 和原始類型 List 之間的差別?

原始List 沒有類型限制,add 或者 get 的時候,接收或傳回的對象類型是Object,是以在add時任何類型的對象均可,get時傳回值類型為Object。List也沒有指派限定,即任何隻要是集合類的對象均可,包括有類型限定的集合。

List<?>,即通配符類型,其引用變量,同樣可以接受任何對應List的參數化類型,包括List,但是一旦指派了,就隻能remove、clear,不能add,保證了安全性和表述性。但不具有表述性,從中取出的元素時Object類型,要通過手動轉換才能得到原本的類型。

List< Object> 有類型限制,類型限制為Object,但由于Object是所有類型的父類,是以在add時任何類型的對象均可,get時傳回值類型也為Object。List< Object>也有指派限定,隻有類型是Object的集合對象才能指派給List< Object>。

【參考連結】https://blog.csdn.net/qq_28411869/article/details/87880039

→ 反射

反射與工廠模式、反射的作用

反射機制: 反射機制是在運作(不是編譯期)狀态中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意一個方法和屬性;這種動态擷取的資訊以及動态調用對象的方法的功能稱為java語言的反射機制。

jdk提供了三種方式擷取一個對象的Class,就User user來說:

1.user.getClass(),這個是Object類裡面的方法

2.User.Class屬性,任何的資料類型,基本資料類型或者抽象資料類型,都可以通過這種方式擷取類

3.Class.forName(""),Class類提供了這樣一個方法,讓我們通過類名來擷取到對象類

反射機制的優缺點:優點是可以實作動态建立對象和編譯,展現出很大的靈活性。缺點是對性能有影響。

工廠模式分為三種:

  • 簡單工廠模式(Simple Factory)
  • 工廠方法模式(Factory Method)
  • 抽象工廠模式(Abstract Factory)

其中簡單工廠模式是工廠方法模式的一種特例。

Class.forName(fullName).newInstance()

使用反射機制實作的工廠模式可以通過反射取得接口的執行個體,但是需要傳入完整的包和類名。而且使用者也無法知道一個接口有多少個可以使用的子類,是以我們可以使用屬性檔案配置所需要的子類。

反射的作用:

​ 反編譯:.class -> java

  • 在運作時判斷任意一個對象所屬的類;
  • 在運作時構造任意一個類的對象;
  • 在運作時判斷任意一個類所具有的成員變量和方法;
  • 在運作時調用任意一個對象的方法;
  • 生成動态代理

Class 類、java.lang.reflect.*

在java.lang.reflect包中有三個類Field, Method, Contructor分别用于描述類的域, 方法和構造器

Field類中有一個getType方法,用來傳回描述域所屬類型的Class對象。

Method 和 Contructor 類有能夠報告參數類型的方法,Method類還有一個可以報告傳回類型的方法。

三個類都有一個叫做getModifiers的方法, 它将傳回一個整形數值, 用不同的位開關描述public和static 這樣的描述符的使用情況。

java.lang.reflect包中的Modifier類的靜态方法分析getModifiers()傳回的整形數值。 例如,可以使用Modifier類中的isPublic、isPrivate、isFinal判斷權限修飾符。

Class類中的getFields,getMethods和getContructors 方法将分别傳回類提供的public域,方法,和構造器數組,其中包括超類的公有成員。

Class類的getDeclareFields、getDeclareMethods和getDeclareContructors 方法将分别傳回類中聲明的全部域、方法和構造器,其中包括私有的和受保護的成員,但不包括超類的成員。

【參考連結】https://blog.csdn.net/q5706503/article/details/84892959

→ 注解

元注解、自定義注解、注解與反射的結合

元注解:

元注解:

  • Documented——指明擁有這個注解的元素可以被javadoc此類的工具文檔化。這種類型應該用于注解那些影響客戶使用帶注釋的元素聲明的類型。如果一種聲明使用Documented進行注解,這種類型的注解被作為被标注的程式成員的公共API 。
  • Inherited——指明該注解類型被自動繼承。如果使用者在目前類中查詢這個元注解類型并且目前類的聲明中不包含這個元注解類型,那麼也将自動查詢目前類的父類是否存在Inherited元注解,這個動作将被重複執行知道這個标注類型被找到,或者是查詢到頂層的父類。
  • Retention——指明在什麼級别顯示此注解
  • Target——指明該類型的注解可以注解的程式元素的範圍

Target主要的參數類型包括以下幾種

  • ElementType.TYPE 用于類,接口,枚舉但不能是注解
  • ElementType.FIELD 作用于字段,包含枚舉值
  • ElementType.METHOD 作用于方法,不包含構造方法
  • ElementType.PARAMETER 作用于方法的參數
  • ElementType.CONSTRUCTOR 作用于構造方法
  • ElementType.LOCAL_VERIABLE 作用于本地變量或者catch語句
  • ElementType.ANNOTATION_TYPE 作用于注解
  • ElementType.PACKAGE 作用于包

Retention主要的參數類型包括以下幾種

  • RetentionPolicy.SOURCE 注解存在于源代碼中,編譯時會被抛棄
  • RetentionPolicy.CLASS 注解會被編譯到class檔案中,但是JVM會忽略
  • RetentionPolicy.RUNTIME JVM會讀取注解,同時會儲存到class檔案中

自定義注解:

注解其實就是一種标記,可以在程式代碼中的關鍵節點(類、方法、變量、參數、包)上打上這些标記,然後程式在編譯時或運作時可以檢測到這些标記進而執行一些特殊操作。

  • 一,定義注解——相當于定義标記; 定義一個@interface類型,加上元注解,定義屬性
  • 二,配置注解——把标記打在需要用到的程式代碼中;
  • 三,定義AOP,解析注解——在編譯期或運作期利用反射擷取注解,并進行特殊操作。

注解與反射的結合 :

首先反射注解,那麼保留政策必須是Runtime,也就是@Retention(RetentionPolicy.RUNTIME) 。在Java中,通過反射,我們可以知道每一個類的詳細資訊,比如有什麼字段,有什麼方法,類名等等,我們通過注解和反射配合,使用反射調用類中的方法,然後讀取注解的參數來進行方法的執行。

Java常用注解

JDK自帶注解有: @Override @Deprecated @Suppvisewarnings

Spring注解: @Repository @Service @Transactional @Controller @Component @Autowired @RequestMapping @ResponseBody @RequestParam @PathVariable @RequestBody @Method @Configuration @Scope @Lazy @PostConstruct @PreDestory @Qualifier @Resource @ModelAttribute @SessionAttributes @DependsOn @Primary @Async

Mybatis注解: @InsertProvider @DeleteProvider @UpdateProvider @SelectProvider @Options @Insert @Select @Update @Delete @Param @Result @Results

青春有你-Java基礎篇(2.5)

→ 序列化

什麼是序列化與反序列化、為什麼序列化、序列化底層原理、序列化與單例模式、protobuf、為什麼說序列化并不安全

序列化:把對象轉換為位元組序列的過程稱為對象的序列化。

反序列化:把位元組序列恢複為對象的過程稱為對象的反序列化。

當兩個程序進行遠端通信時,可以互相發送各種類型的資料,包括文本、圖檔、音頻、視訊等, 而這些資料都會以二進制序列的形式在網絡上傳送。 發送方需要把這個Java對象轉換為位元組序列,然後在網絡上傳送;另一方面,接收方需要從位元組序列中恢複出Java對象。

序列化優點:

(1)永久性儲存對象,儲存對象的位元組序列到本地檔案或者資料庫中;

(2)通過序列化以位元組流的形式使對象在網絡中進行傳遞和接收;

(3)通過序列化在程序間傳遞對象;

底層原理:

1、JDK類庫中序列化和反序列化API

(1)java.io.ObjectOutputStream:表示對象輸出流。它的writeObject(Object obj)方法可以對參數指定的obj對 象進行序列化,把得到的位元組序列寫到一個目标輸出流中;

(2)java.io.ObjectInputStream:表示對象輸入流:它的readObject()方法源輸入流中讀取位元組序列,再把它們 反序列化成為一個對象,并将其傳回;

2、實作序列化的要求

隻有實作了Serializable或Externalizable接口的類的對象才能被序列化,否則抛出異常!

序列化與單例模式:

序列化會破壞單例模式, 因為序列化會通過反射調用無參數的構造方法建立一個新的對象。

ProtoBuf 是結構資料序列化 方法,可簡單類比于 XML,其具有以下特點:

  • 語言無關、平台無關。即 ProtoBuf 支援 Java、C++、Python 等多種語言,支援多個平台
  • 高效。即比 XML 更小(3 ~ 10倍)、更快(20 ~ 100倍)、更為簡單
  • 擴充性、相容性好。你可以更新資料結構,而不影響和破壞原有的舊程式

protobuf 序列化後 生成 std::string 然後将std::string 轉化為 QString 再反轉回 std::string 進行反序列化 發現生成的值不對。

最常見的反序列化安全問題是通過修改序列化之後的資料字段, 抽象來看,隻要是從Application之外讀取或接收資料,并将其反序列化成Application或API中的對象,都可能存在反序列化安全問題。

【相關連結】https://blog.csdn.net/Roger_CoderLife/article/details/86704380

https://www.ibm.com/developerworks/cn/linux/l-cn-gpb/index.html

→ 正規表達式

java.lang.util.regex.*

正規表達式(regular expression)描述了一種字元串比對的模式(pattern),可以用來檢查一個串是否含有某種子串、将比對的子串替換或者從某個串中取出符合某個條件的子串等。

青春有你-Java基礎篇(2.5)

→ 常用的 Java 工具庫

commons.lang3、commons.*…、 guava-libraries、 netty

commons-lang3: StringUtils

common-beanutils: BeanUtils

commons-io: IOUtils

Guava-Libraries是google對java的一個擴充,主要涵蓋集合、緩存、并發、I/O、反射等等。

netty參考: https://www.cnblogs.com/imstudy/p/9908791.html