主頁 > 後端開發 > Java中泛型詳解,非常詳細

Java中泛型詳解,非常詳細

2023-05-31 10:09:33 後端開發

前言

在前面的幾篇文章中,詳細地給大家介紹了Java里的集合,但在介紹集合時,我們涉及到了泛型的概念卻并沒有詳細學習,所以今天我們要花點時間給大家專門講解什么是泛型、泛型的作用、用法、特點等內容,

有些粉絲朋友,在之前就一直很好奇,比如List< String >中的 < String > 部分到底是什么?有啥用?為什么要加這個< >?這一部分有沒有什么特別的用法?總之,你的疑問可能會有很多,別急,今天就帶你一點點認識Java里的泛型!


全文大約【6000】 字,不說廢話,只講可以讓你學到技術、明白原理的純干貨!本文帶有豐富的案例及配圖視頻,讓你更好地理解和運用文中的技術概念,并可以給你帶來具有足夠啟迪的思考...

一. 泛型簡介

作為Java中常用且重要的一個概念,泛型幫我們實作了代碼重用,也保證了型別安全,但關于它的詳細內容,目前很多同學還不清楚,所以接下來就帶各位來學習這個重要的知識點,

1. 背景

為了能夠讓大家更好地理解泛型的作用,在我們開始學習泛型之前,先給大家提個開發需求:

我們現在有一個需求,要求你撰寫一個對陣列進行排序的方法,該方法能夠對浮點型陣列、整型陣列、字串陣列或者是其他任何型別的陣列進行排序,你該如何實作?

有的小伙伴會說,這很簡單啊,我可以利用方法多載,針對每種型別的陣列分別撰寫一個排序方法,需要為幾種型別的陣列排序,我就定義幾個排序方法,如果你是這么實作的,只能哈哈哈了,這種做法明顯不好,代碼可重用性太差

又有的小伙伴說了,可以定義一個方法,里面設定一個Object[]型別的引數,這樣無論是哪種型別都可以處理了,這樣定義方法,比上面那個同學的想法要稍好一點,但此時我們需要在Object型別和整型、String型別或其他型別之間進行強制型別轉換,所以這樣做就無法保證集合中元素的型別安全,稍一不慎就可能會導致 ClassCastException型別轉換例外

so,這也不行,那也不行,到底該怎么辦?這不,為了解決這些問題,所以Java中就產生了泛型這個技術,

2. 概念

泛型(generics) 這個技術是在JDK 5中引入的新特性,它的本質其實是型別引數化, 利用泛型可以實作一套代碼對多種資料型別的動態處理,保證了更好的代碼重用性,并且泛型還提供了編譯時對型別安全進行檢測的機制,該機制允許我們在編譯時就能夠檢測出非法的型別, 提高了代碼的安全性

這種特性,使得泛型成了一種 “代碼模板” ,讓我們利用一套代碼就能實作對各種型別的套用,也就是說,我們只需要撰寫一次代碼,就可以實作萬能匹配,這也是”泛型“這個概念的含義,你可以將其理解為”廣泛的型別“、”非特定的型別“,咱們上面的那個需求,利用泛型就能輕松實作,還不需要進行型別的強制轉換,并且也保證了資料的型別安全,

3. 作用

所以根據上面泛型的概念,我們可以提取出泛型的核心作用:

  • 泛型可以在編譯時對型別進行安全檢測,使得所有的強制轉換都是自動隱式實作的,保證了型別的安全性;
  • 泛型作為”代碼模板“,實作了 一套代碼對各種型別的套用, 提高了代碼的可重用性,

4. 使用場景

基于泛型的這些特性和作用,我們可以把泛型用在很多地方,在這里給大家做了一個總結,通常情況下,泛型可以用在如下場景中:

  • 泛型集合:在各種集合中使用泛型,保證集合中元素的型別安全;
  • 泛型方法:在各種方法中使用泛型,保證方法中引數的型別安全;
  • 泛型類:在類的定義時使用泛型,為某些變數和方法定義通用的型別;
  • 泛型介面:在介面定義時使用泛型,為某些常量和方法定義通用的型別;
  • 泛型加反射:泛型也可以結合反射技術,實作在運行時獲取傳入的實際引數等功能,

但是我們要注意,無論我們在哪個地方使用泛型,泛型都不能是基本型別, 關于這一點,我會在講解泛型擦除時再細說,

總之,泛型的應用場景有很多,以上只是給大家總結的幾個重點使用場景,接下來就這幾個場景分別給大家進行講解,

5. 配套視頻

與本節內容配套的視頻鏈接如下:戳我直達

二. 泛型集合

1. 簡介

泛型最常見的一個用途,就是在集合中對資料元素的型別進行限定,集合作為一個容器,主要是用來容納保存資料元素的,但集合的設計者并不知道我們會用集合來保存什么型別的物件,所以他們就把集合設計成能保存任何型別的物件,這就要求集合具有很好的通用性,內部可以裝載各種型別的資料元素,集合之所以可以實作這一功能,主要是集合的原始碼中已經結合泛型做了相關的設計,我們來看看Collection的原始碼,如下圖所示:

image.png

而Collection的子類List中也增加了對泛型的支持,如下圖所示:

image.png

上面的原始碼中,集合中的< E >就是泛型,至于泛型的名字為什么叫做”E“,后面再跟大家細說,但不管如何,從這些原始碼中我們就可以看出,Java的集合本身就支持泛型了,我們先不管集合底層是如何設計的,咱們先從基本用法開始學起,

2. 語法

在集合中使用泛型其實比較簡單,我們以List集合為例,其基本語法如下:

//可以省略后面ArrayList里的String,編譯器可以自動根據前面<>里的型別,推斷出后面<>里使用的泛型型別
List<String> list = new ArrayList<>();

上面的語法,其含義是說我們定義了一個ArrayList集合,但該集合不能隨便添加資料元素,只能添加String型別的元素,也就是說,在上面的語法中,我們通過泛型,限定了ArrayList集合的元素型別,當我們定義List集合時,如果已經限定了泛型型別,但后面添加元素時你非得違背這個型別,Java就會在編譯階段報錯,如下圖所示:

image.png

我們在定義集合時,可以省略后面ArrayList里的String,編譯器可以自動根據前面< >里的型別,推斷出后面< >里使用的泛型型別,另外Set和Map集合的用法,與List集合類似,我們可以通過下面這個案例來體會一下集合泛型的魅力,

3. 代碼案例

在本案例中,我們可以給List、Set、Map等集合設定泛型,從而限定集合中資料元素的型別,

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class Demo01 {
	public static void main(String[] args) {
		//定義集合泛型
		//此時的集合只能接受String型別元素,后面ArrayList<>中的<>,里面的String可寫可不寫
		List<String> list = new ArrayList<>();
		//如果型別不一致,在編譯階段就會檢測出有錯誤,保證了資料的安全性
		//list.add(100);
		list.add("Hello");
		String strValue = https://www.cnblogs.com/qian-fen/p/list.get(0);
		System.out.println("list value="https://www.cnblogs.com/qian-fen/p/+strValue);
		
		Set set=new HashSet<>();
		//set.add("hello");
		set.add(200);
		Iterator<Integer> iterator = set.iterator();
		while(iterator.hasNext()) {
			Integer nextValue = https://www.cnblogs.com/qian-fen/p/iterator.next();
			System.out.println("set value="https://www.cnblogs.com/qian-fen/p/+nextValue);
		}
		
		//限定Map集合的key是String型別,value是Long型別
		Map map=new HashMap<>();
		//map.put("number", "10000");
		map.put("number", 10000L);
		Long value = https://www.cnblogs.com/qian-fen/p/map.get("number");
		System.out.println("map value="https://www.cnblogs.com/qian-fen/p/+value);
	}
}

在這個案例中,我們在集合中通過泛型限定了集合元素的資料型別,如果元素的型別與要求的不一致,在編譯階段就會檢測出有錯誤,不需要進入到運行階段才能發現型別不一致,而且我們 在獲取集合中的元素時,也不需要進行強制型別轉換,程式會自動進行隱式轉換, 這就保證了資料的安全性,也提高了代碼的執行效率,

另外我們所使用的泛型引數,也被稱為型別變數,是用于指定泛型型別名稱的識別符號,我們可以根據需要,在集合、類、介面、方法等地方定義一個或多個泛型引數,這些泛型化的型別引數也被稱為引數化的類或引數化的型別,

4. 配套視頻

與本節內容配套的視頻鏈接如下:戳我直達

三. 泛型介面

我們除了可以在集合中使用泛型,還可以在定義介面時使用泛型,這也是泛型的常用形式之一,

1. 語法

在定義介面時使用泛型的基本語法格式如下:

//在介面名稱后面緊跟泛型<>
public interface InterfaceName<T> {
    // 介面的方法定義
}

//可以同時定義多個泛型,多個泛型用","逗號分割
public interface InterfaceName2<M,N> {
    // 介面的方法定義
}

大家注意,這里泛型的名稱T/M/N,其實是我們隨意寫的,我們并不一定非要使用T,也可以使用M、N、E等任意名稱,而之所以使用T,只是采用了Type型別這個單詞的首字母而已,雖然如此,但我們在實際開發時,為了盡量做到見名知意,請大家還是要盡量采用有意義的名稱,通常會使用如下幾個常用字母:

  • E - Element(表示集合元素,常在集合中使用);
  • T - Type(表示Java類,常用在類和介面中);
  • K - Key(表示鍵);
  • V - Value(表示值);
  • N - Number(表示數值型別);
  • - 表示不確定的Java型別,

另外,這里的T只是一種型別引數,你可以把它理解成是一個”表面的占位符“,在真正賦值時,它可以用任何實際的型別來替代,如Integer、String、自定義型別等,并且我們在定義介面時,可以根據實際需要,同時定義多個泛型,多個泛型之間用","逗號分割,而在實際使用時,我們需要在該介面名的后面加上一對尖括號,用來傳入實際的型別,

2. 代碼案例

2.1 定義泛型介面

接下來我們再通過一個案例來學習一下介面泛型如何使用,這里我們定義一個泛型介面ICompute,內部定義了一個用于計算的方法,如下所示:


public interface ICompute<M,N> {

	//定義一個加法計算的方法
	M add(M m,N n);
}

2.2 實作泛型介面

接下來我們把這個介面進行實作,代碼如下:

public class Demo02 {
	public static void main(String[] args) {
		//這里壹哥直接利用匿名內部類的寫法進行實作,大家也可以撰寫一個類實作ICompute介面
		//我這里傳入了兩個Integer型別的具體引數,分別取代M和N
		ICompute<Integer, Integer> iCompute = new ICompute<Integer, Integer>() {
			@Override
			public Integer add(Integer m, Integer n) {
				return m+n;
			}
		};
		
		//呼叫上面實作的方法
		Integer result = iCompute.add(100, 200);
		System.out.println("result="+result);
	}
}

這里直接利用匿名內部類的寫法進行實作,大家也可以撰寫一個類實作ICompute介面,我這里傳入了兩個Integer型別的具體引數,分別取代M和N,當然我們也可以根據需要,在實作時傳入Float/Double等其他型別,

3. 配套視頻

與本節內容配套的視頻鏈接如下:戳我直達

四. 泛型類

其實Java的類和介面在很多地方都很類似,所以我們在定義介面時可以使用泛型,也可以在定義類時使用泛型,泛型類常用于類中的屬性型別不確定的情況下,這也是泛型的常用形式之一,

1. 語法

其實泛型類的宣告和普通類的宣告類似,只是在類名后面多添加了一個關于泛型的宣告,并且泛型類的型別引數部分,可以包含一個或多個型別引數,多個引數間用逗號隔開,一般我們在定義泛型類時,需要在類名后添加型別引數,語法格式與泛型介面一致,如下所示:

public class ClassName<T> {
    // 類的成員變數和方法定義
}

泛型類的要求和泛型介面完全一樣,這里就不再贅述了,

2. 代碼案例

2.1 定義泛型類

接下來定義一個泛型類Pair,它包含兩個型別相同的成員變數:

public class Pair<T> {

	//我們可以直接把泛型當成一個java的“型別”來用,Java類怎么用,泛型就可以怎么用
	//直接利用泛型來定義成員變數
	private T first;
    private T second;

    //構造方法中使用泛型
    public Pair(T first, T second) {
        this.first = first;
        this.second = second;
    }

    //方法中使用泛型
    public T getFirst() {
        return first;
    }

    public T getSecond() {
        return second;
    }
}

在上述代碼中,我們定義了一個泛型類Pair,它有兩個型別相同的成員變數first和second,以及一個建構式和兩個訪問成員變數的方法,在定義Pair類時,我們使用了型別引數T來代表型別,而在實體化該泛型類時,需要指明泛型類中的型別引數,并賦予泛型類屬性相應型別的值,比如指定T是String/Integer/Student/Person等任意型別,

2.2 使用泛型類

接下來是使用Pair類的具體代碼:


public class Demo03 {
	public static void main(String[] args) {
		//呼叫泛型類
		Pair<String> pair = new Pair<>("Hello", "World");
		// 輸出 "Hello"
		System.out.println("first="+pair.getFirst()); 
		// 輸出 "World"
		System.out.println("last="+pair.getSecond()); 
	}
}

在上述代碼中,我們使用了Pair類,并將型別引數指定為String型別,然后我們創建了一個Pair物件,并通過getFirstgetSecond方法訪問了成員變數,

3. 配套視頻

與本節內容配套的視頻鏈接如下:戳我直達

五. 繼承泛型類和實作泛型介面

在Java中,泛型不僅可以用于類、方法的定義,還可以用于類和介面的繼承與實作,接下來就給大家詳細介紹一下,該如何繼承泛型類和實作泛型介面,

1. 簡介

大家要注意,一個被定義為泛型的類和介面,也可以被子類繼承和實作,例如下面的示例代碼,就給大家演示了如何繼承一個泛型類,

public class FatherClass<T1>{}

public class SonClass<T1,T2,T3> extents FatherClass<T1>{}

但是如果我們想要SonClass類在繼承FatherClass類時,能夠保留父類的泛型型別,則需要在繼承時就指定,否則直接使用extends FatherClass陳述句進行繼承操作時,T1、T2 和 T3都會自動變為Object型別,所以一般情況下都是將父類的泛型型別保留,

接下來會分別給大家介紹一下如何繼承泛型類和實作泛型介面,

2. 繼承泛型類

2.1 定義泛型父類

在Java中,我們可以通過繼承一個泛型類來實作泛型的重用,子類可以繼承父類中定義的泛型型別,并根據自己的需要,增加、修改泛型型別的引數,從而實作泛型類的個性化定制,下面是一個泛型類的示例:

public class GenericClass<T1> {

	private T1 data;

	public GenericClass(T1 data) {
		this.data = https://www.cnblogs.com/qian-fen/p/data;
	}

	public T1 getData() {
		return data;
	}
}

2.2 泛型子類繼承父類

我們可以通過繼承GenericClass類,來創建一個新的泛型類SonGenericClass,并增加新的泛型型別:

public class SonGenericClass<T1,T2> extends GenericClass<T1>{

	private T2 otherData;
    
    public SonGenericClass(T1 data, T2 otherData) {
        super(data);
        this.otherData = https://www.cnblogs.com/qian-fen/p/otherData;
    }
    
    public T2 getOtherData() {
        return otherData;
    }
}

在上面的示例中,SonGenericClass類繼承了GenericClass類,并增加了一個新的泛型型別T2,在構造方法中,呼叫父類的構造方法,并傳入T1型別的資料,然后再將T2型別的資料賦值給類的成員變數otherData,通過這種方式,我們可以創建一個具有更多泛型引數的類,并且保留了原始泛型類的特性,我們來看看最終的測驗結果:

public class Demo08 {

	public static void main(String[] args) {
		SonGenericClass<Integer,String> son=new SonGenericClass<>(100, "hello");
        //子類從父類中繼承來的泛型
		Integer data = https://www.cnblogs.com/qian-fen/p/son.getData();
		String otherData = son.getOtherData();
		System.out.println("t1---data="https://www.cnblogs.com/qian-fen/p/+data+",t2---data="https://www.cnblogs.com/qian-fen/p/+otherData);
	}
}

這樣,子類通過繼承父類,也自動獲得了父類中的泛型,

3. 實作泛型介面

3.1 定義泛型介面

類似于繼承泛型類,我們也可以通過實作泛型介面,來定義具有多個泛型引數的介面,實作泛型介面的程序與實作普通介面的程序相同,我們只需要在介面名后面添加 < T > 這樣的泛型引數宣告即可,下面是一個泛型介面的示例:

public interface GenericInterface<T1> {
	
	public void doSomething(T1 data);
}

3.2 兩種實作方式

我們在實作泛型介面時,可以采用兩種實作方式:

  1. 指定具體型別:就是在實作介面時,明確指定泛型引數的具體型別;
  2. 保留泛型引數:在實作介面時,不明確指定泛型引數的具體型別,而是保留泛型引數,

如果是通過指定具體型別的方式進行實作,一般形式如下:

public class StringPair implements Pair<String> {
    .....
}

在這種方式中,我們定義了一個Pair介面,然后讓子類StringPair進行實作,但在實作時就明確指定了具體的泛型引數為String,這樣,我們在使用StringPair物件時,就明確知道了類內部的資料型別,

如果是通過保留泛型引數的方式進行實作,一般形式如下:

public class NumberPair<T extends 父型別> implements Pair<T> {
    ......
}

在這種方式中,我們定義了一個泛型介面Pair< T >,然后定義一個實作字類NumberPair,可以在實作時保留泛型引數,

3.3 實作泛型介面

接下來,我們再撰寫一個SubGenericInterface類,并通過保留泛型引數的方式,來實作GenericInterface介面,并增加一個新的泛型型別T2,代碼如下:

public class SubGenericClass<T1,T2> implements GenericInterface<T1>{

	private T2 otherData;
	
	@Override
	public void doSomething(T1 data) {
		System.out.println("t1="+data);
	}
    
    public SubGenericClass(T2 otherData) {
        this.otherData = https://www.cnblogs.com/qian-fen/p/otherData;
    }
    
    public T2 getOtherData() {
        return otherData;
    }

}

這樣泛型子類就實作了泛型父類,并在子類中增加了一個新的泛型,最終的結果如下所示:

public class Demo09 {

	public static void main(String[] args) {
		SubGenericClass<Integer,String> sub=new SubGenericClass<>("hello");
		sub.doSomething(100);
		String otherData = https://www.cnblogs.com/qian-fen/p/sub.getOtherData();
		System.out.println("t2---data="https://www.cnblogs.com/qian-fen/p/+otherData);
	}
}

其實,實作泛型介面和繼承泛型類都很簡單,我們只需要在類定義中使用相同的泛型型別引數,然后實作介面的方法或覆寫超類的方法即可,

以上就是關于泛型的概念、作用、泛型介面、泛型類等相關的內容,其實泛型的內容還有很多,比如泛型方法、泛型擦除和泛型中的通配符等,但受限于篇幅,會在下一篇文章中繼續給大家講解這些內容,敬請繼續關注哦,


五. 結語

至此,在本文中就把泛型的概念、作用、泛型介面和泛型類給大家介紹完了,本文重點內容如下:

  • 泛型是一種型別引數,可以撰寫模板代碼來適應任意型別;
  • 泛型在使用時不必對型別進行強制轉換,它可以通過編譯器在編譯階段對型別進行檢查;
  • 使用泛型時可以把泛型引數< T >替換成想要的class型別,例如 ArrayList< String> ArrayList< Number >等;
  • 編譯器可以根據前面的泛型,在后面自動推斷出型別,例如List< String > list = new ArrayList<>();
  • 如果我們在使用時不指定泛型引數型別時,編譯器會給出警告,且只能將 < T >視為Object型別;
  • 我們可以在介面和類中定義泛型型別,實作此介面的類必須傳入正確的泛型型別;
  • 我們可以同時定義多個泛型,例如 Map<K, V>
  • 可以繼承泛型類和實作泛型介面,

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/553917.html

標籤:Java

上一篇:keycloak~自定義登出介面

下一篇:返回列表

標籤雲
其他(160059) Python(38189) JavaScript(25466) Java(18163) C(15235) 區塊鏈(8268) C#(7972) AI(7469) 爪哇(7425) MySQL(7219) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5873) 数组(5741) R(5409) Linux(5344) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4580) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2434) ASP.NET(2403) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) .NET技术(1979) 功能(1967) Web開發(1951) HtmlCss(1950) C++(1928) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1879) .NETCore(1863) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Java中泛型詳解,非常詳細

    # 前言 在前面的幾篇文章中,詳細地給大家介紹了Java里的集合。但在介紹集合時,我們涉及到了泛型的概念卻并沒有詳細學習,**所以今天我們要花點時間給大家專門講解什么是泛型、泛型的作用、用法、特點等內容。** 有些粉絲朋友,在之前就一直很好奇,比如List中的 部分到底是什么?有啥用?為什么要加這個 ......

    uj5u.com 2023-05-31 10:09:33 more
  • keycloak~自定義登出介面

    keycloak提供了登出的介面,不過它是一個post方法,需要你根據client_id,client_secret及refresh_token進行登出操作的,有時不太靈活,所以我又自己封裝了一下,通過客戶端瀏覽器上存盤的session_id進行會話登出。 # kc提供的logout * api:{ ......

    uj5u.com 2023-05-31 10:09:26 more
  • 驅動開發:內核決議PE結構匯出表

    在筆者的上一篇文章`《驅動開發:內核特征碼掃描PE代碼段》`中`LyShark`帶大家通過封裝好的`LySharkToolsUtilKernelBase`函式實作了動態獲取內核模塊基址,并通過`ntimage.h`頭檔案中提供的系列函式決議了指定內核模塊的`PE節表`引數,本章將繼續延申這個話題,實... ......

    uj5u.com 2023-05-31 10:03:24 more
  • Java中如何中斷執行緒

    在Java中,可以使用以下方法中斷執行緒: 1. 使用`interrupt()`方法:每個執行緒物件都有一個`interrupt()`方法,用于中斷該執行緒。當呼叫執行緒的`interrupt()`方法時,它會設定執行緒的中斷狀態為"中斷",但并不會立即停止執行緒的執行。執行緒在執行程序中可以通過檢查中斷狀態來決 ......

    uj5u.com 2023-05-31 08:14:02 more
  • java注解與反射

    # java注解與反射 - java注解與反射十分重要,是很多框架的底層 ## 注解(Annotataion) - 注解的作用: 1. 不是程式本身,可以對程式作出解釋 1. 可以被其他程式讀取 - 注解的格式:@注釋名,如@override表示重寫方法,而且有些還可以添加一些引數值,如@Suppr ......

    uj5u.com 2023-05-31 08:08:28 more
  • Python連接es筆記三之es更新操作

    > 本文首發于公眾號:Hunter后端 > 原文鏈接:[Python連接es筆記三之es更新操作](https://mp.weixin.qq.com/s/1cTaVfjLFrmbXajNcayhEA) 這一篇筆記介紹如何使用 Python 對資料進行更新操作。 對于 es 的更新的操作,不用到 Se ......

    uj5u.com 2023-05-31 08:03:03 more
  • 騰訊二面:有 40 億個 QQ 號,限制 1G 記憶體,問如何去重?被問懵了!

    > 40億個QQ號,限制1G記憶體,如何去重? 40億個unsigned int,如果直接用記憶體存盤的話,需要: `4*4000000000 /1024/1024/1024 = 14.9G` ,考慮到其中有一些重復的話,那1G的空間也基本上是不夠用的。 想要實作這個功能,可以借助位圖。 使用位圖的話, ......

    uj5u.com 2023-05-31 07:56:52 more
  • JavaWeb

    # JavaWeb ## 1、基本概念 ### 1.1、前言 web開發: - web,網頁的意思 - 靜態web - html,css - 提供給所有人看的資料始終不會發生變化 - 動態web - 幾乎所有的網站都是動態的 - 提供給所有人看的資料始侄訓發生變化,每個人在不同的時間,不同的地點看到 ......

    uj5u.com 2023-05-31 07:50:35 more
  • 新版idea快捷鍵總結學習----(用于java開發模式)

    ### 選擇代碼區 1. ctrl w - 如果放到以if開頭的陳述句,可以選擇if判斷條件所在的代碼片段 - 游標在單個單詞下時 選擇單詞 - 在選中多個單詞時,選擇整個字串 - 三次點擊時,如果不在字串單詞下,用于選擇{}內的代碼片段 逐級遞增 如果在單詞下方,用于選擇單詞所在的字串并且向外 ......

    uj5u.com 2023-05-31 07:50:18 more
  • geowebCache 切片不同方式的呼叫

    1.curl 方式 curl -v -u admin:geoserver -H "Content-type: application/json" -d "{'seedRequest':{'name':'NR:tdbp','bounds':{'coords':{ 'double':[ '108.790 ......

    uj5u.com 2023-05-31 07:50:09 more