日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java写dnf外掛_dnf卡盟_Java的泛型详解(一)

發(fā)布時間:2023/12/4 java 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java写dnf外掛_dnf卡盟_Java的泛型详解(一) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Java實現(xiàn)DDD中UnitOfWorkdnf卡盟

Java的泛型詳解

泛型的利益

編寫的代碼可以被差別類型的工具所重用。

由于上面的一個優(yōu)點,泛型也可以削減代碼的編寫。

泛型的使用

簡樸泛型類

public class Pair {

private T first;

private T second;

public Pair() {

first = null;

second = null;

}

public Pair(T first, T second){

this.first = first;

this.second = second;

}

public T getFirst(){

return first;

}

public T getSecond(){

return second;

}

public void setFirst(T first) {

this.first = first;

}

public void setSecond(T second) {

this.second = second;

}

}

上面例子可以看出泛型變量為T;

用尖括號(<>)括起來,并放在類名后面;

泛型還可以界說多個類型變量好比上面的例子 first和second差別的類型:

public class Pair {....}

注: 類型變量的界說需要一定的規(guī)范:

(1) 類型變量使用大寫形式,而且要比較短;

(2)常見的類型變量稀奇代表一些意義:變量E 示意聚集類型,K和V示意要害字和值的類型;T、U、S示意隨便類型;

類界說的類型變量可以作為方式的返回類型或者局部變量的類型;

例如: private T first;

用詳細的類型替換類型變量就可以實例化泛型類型;

例如: Pair 代表將上述所有的T 都替換成了String

由此可見泛型類是可以看作通俗類的工廠

泛型方式

我們應(yīng)該若何界說一個泛型方式呢?

泛型的方式可以界說在泛型類,也可以界說在通俗類,那若是界說在通俗類需要有一個尖括號加類型來指定這個泛型方式詳細的類型;

public class TestUtils {

public static T getMiddle(T... a){

return a[a.length / 2];

}

}

類型變量放在修飾符(static)和返回類型的中心;

當你挪用上面的方式的時刻只需要在方式名前面的尖括號放入詳細的類型即可;

String middle = TestUtils.getMiddle("a", "b", "c");

若是上圖這種情形實在可以省略 ,由于編譯器能夠推斷出挪用的方式一定是String,以是下面這種挪用也是可以的;

String middle = TestUtils.getMiddle("a", "b", "c");

然則若是是以下挪用可能會有問題:

如圖:可以看到變意思沒有辦法確定這里的類型,由于此時我們?nèi)雲(yún)⑼▓罅艘粋€Double3.14 兩個Integer1729 和0 編譯器以為這三個不屬于同一個類型;

此時有一種解決辦法就是把整型寫成Double類型

類型變量的限制

有時刻我們不能無限制的讓使用者通報隨便的類型,我們需要對我們泛型的方式舉行限制通報變量,好比如下例子

盤算數(shù)組中最下的元素

這個時刻是無法編譯通過的,且編譯器會報錯

由于我們的編譯器不能確定你這個T 類型是否有compareTo這個函數(shù),以是這么能讓編譯器信賴我們這個T是一定會有compareTo呢?

我們可以這么寫 這里的意思是T一定是繼續(xù)Comparable的類

由于Comparable是一定有compareTo這個方式,以是T一定有compareTo方式,于是編譯器就不會報錯了

由于加了限制那么min這個方式也只有繼續(xù)了Comparable的類才可以挪用;

若是要限制方式的泛型繼續(xù)多個類可以加extends 要害字并用&支解如:T extends Comparable & Serializable

限制類型是用&支解的,逗號來支解多個類型變量

類型擦除

豈論什么時刻界說一個泛型類型,虛擬機都市提供一個響應(yīng)的原始類型(raw type)。原始類型的名字就是刪掉類型參數(shù)后的泛型類型。擦除類型變量,并替換限制類型(沒有限制類型的變量用Object)

列如: Pair 的原始類型如下所示

public class Pair {

private Object first;

private Object second;

public Pair() {

first = null;

second = null;

}

public Pair(Object first, Object second){

this.first = first;

this.second = second;

}

public Object getFirst(){

return first;

}

public Object getSecond(){

return second;

}

public void setFirst(Object first) {

this.first = first;

}

public void setSecond(Object second) {

this.second = second;

}

}

由于上面的T是沒有限制變量,于是用Object取代了;

若是有限制變量則會以第一個限制變量替換為原始類型如:

public class Interval implements Serializable{

private T lower;

private T upper;

}

原始類型如下所示:

public class Interval implements Serializable{

private Comparable lower;

private Comparable upper;

}

翻譯泛型表達式

上面說到泛型擦除類型變量后對于無限制變量后會以O(shè)bject來替換泛型類型變量;

然則我們使用的時刻并不需要舉行強制類型轉(zhuǎn)換;

原因是編譯器已經(jīng)強制插入類型轉(zhuǎn)換;

例如:

Pair buddies = ...;

Employee buddy = buddies.getFirst();

擦除getFirst的返回類型后將返回Object類型,然則編譯器自動插入Employee的強制類型轉(zhuǎn)換,編譯器會把這個方式挪用翻譯為兩條虛擬機指令;

對原始方式Pair.getFirst的挪用

將返回的Object類型強制轉(zhuǎn)換為Employee類型;

我們可以反編譯驗證一下

要害的字節(jié)碼有以下兩條

9: invokevirtual #4 // Method com/canglang/Pair.getFirst:()Ljava/lang/Object;

12: checkcast #5 // class com/canglang/model/Employee

虛擬機指令寄義如下:,dnf論壇,

invokevirtual:虛函數(shù)挪用,挪用工具的實例方式,憑據(jù)工具的現(xiàn)實類型舉行派發(fā),支持多態(tài);

checkcast:用于檢查類型強制轉(zhuǎn)換是否可以舉行。若是可以舉行,checkcast指令不會改變操作數(shù)棧,否則它會拋出ClassCastException異常;

由此我們可以驗證了上述的結(jié)論,在反編譯后的字節(jié)碼中看到,當對泛型表達式挪用時,虛擬機操作如下:

對于工具的現(xiàn)實類型舉行替換泛型;

檢查類型是否可以強制轉(zhuǎn)換,若是可以將對返回的類型舉行強制轉(zhuǎn)換;

翻譯泛型方式

類型擦除也會出現(xiàn)在泛型方式內(nèi)里

public static T min(T[] a)

類型擦除后

public static Comparable min(Comparable[] a)

此時可以看到類型參數(shù)T已經(jīng)被擦除了,只剩下限制類型Comparable;

方式的類型擦除帶來了兩個龐大的問題,看下面的示例:

public class DateInterval extends Pair {

public void setSecond(LocalDate second){

System.out.println("DateInterval: 進來這里了!");

}

}

此時有個問題,從Pair繼續(xù)的setSecond方式類型擦除后為

public void setSecond(Object second)

這個和DateInterval的setSecond顯著是兩個差別的方式,由于他們有差別的類型的參數(shù),一個是Object,一個LocalDate;

那么看下面一個列子

public class Test {

public static void main(String[] args) {

DateInterval interval = new DateInterval();

Pair pair = interval;

pair.setSecond(LocalDate.of(2020, 5, 20));

}

}

Pair引用了DateInterval工具,以是應(yīng)該挪用DateInterval.setSecond。

我們看一下運行效果

然則看了反編譯的字節(jié)碼可能發(fā)現(xiàn)一個問題:

17: invokestatic #4 // Method java/time/LocalDate.of:(III)Ljava/time/LocalDate;

20: invokevirtual #5 // Method com/canglang/Pair.setSecond:(Ljava/lang/Object;)V

這里可以看到此處字節(jié)碼挪用的是Pair.setSecond

這里有個主要的觀點就是橋方式

引用Oracle中對于這個征象的注釋

為了解決此問題并在類型擦除后保留通用類型的?多態(tài)性,

Java編譯器天生了一個橋接方式,以確保子類型能夠按預(yù)期事情。

對于DateInterval類,編譯器為setSecond天生以下橋接方式:

public class DateInterval extends Pair {

// Bridge method generated by the compiler

//

public void setSecond(Object second) {

setSecond((LocalDate)second);

}

public void setSecond(LocalDate second){

System.out.println("DateInterval: 進來這里了!");

}

}

那么我們?nèi)艉悟炞C是否天生這個橋方式呢?我們可以反編譯一下DateInterval.java看一下字節(jié)碼;

public void setSecond(java.lang.Object);

descriptor: (Ljava/lang/Object;)V

flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC

Code:

stack=2, locals=2, args_size=2

0: aload_0

1: aload_1

2: checkcast #5 // class java/time/LocalDate

5: invokevirtual #6 // Method setSecond:(Ljava/time/LocalDate;)V

8: return

我截取了部門發(fā)現(xiàn)在 DateInterval的字節(jié)碼中簡直會有一個橋方式,同時驗證了上面的問題;

總結(jié):

虛擬機中沒有泛型,只有通俗的類和方式

所有的類型參數(shù)都用他們的限制類型替換

橋方式被合成來保持多態(tài)

為保持類型安全性,必要時插入強制類型轉(zhuǎn)換,dnf助手Kubernetes學習筆記(二):Pod、標簽、注解

總結(jié)

以上是生活随笔為你收集整理的java写dnf外掛_dnf卡盟_Java的泛型详解(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。