首頁 > Java > java教程 > Java 中的泛型是什麼?

Java 中的泛型是什麼?

WBOY
發布: 2024-08-30 16:18:36
原創
973 人瀏覽過

Java 中的泛型是一項進階功能,可實現程式碼可重複使用性和類型安全性。程式碼可重用功能是透過定義通用類別、介面、建構函數和方法來實現的。泛型使用資料類型聲明來確保類型安全,從而消除運行時錯誤的機會。尖括號“”符號用於實現泛型,類型參數在括號內定義。這些類型參數包括“T”(類型)、“E”(元素)、“N”(數字)、“K”(鍵)和“V”(值)。具有類型 T 參數的泛型類別的範例是「public class DemoGenericClass」。 {…}’

 

開始您的免費軟體開發課程

網頁開發、程式語言、軟體測試及其他

Java 中泛型是如何實現的?

泛型是使用尖括號「」實現的括號內包含型別參數「T」。例如,在中,類型參數「T」是一個佔位符,表示將在運行時分配資料類型。

泛型類別可以定義為:

代碼:

public class MyGenericClass<T> {…}
登入後複製

以下是標準型別參數:

  • T: 類型
  • E: 元素
  • N: 數字
  • K:鑰匙
  • V:

多參數的情況下,用S、U、V等分別定義第二、三、四參數。

理解 Java 中的泛型

什麼是類型安全以及它如何運作?泛型類別、介面、建構函數和方法與我們的常規類別和方法有何不同,使它們可重複使用?

Java 是一種靜態類型語言,在使用變數之前需要聲明其資料類型。

範例:

代碼:

String myString ="eduCBA";
登入後複製

在上面的程式碼中,「String」是資料類型,「myString」是保存 String 類型值的變數。

現在,如果嘗試傳遞一個布林值來代替字串,如下所示:

代碼:

String myBooleanStr = true;
登入後複製

它將立即導致編譯時錯誤,指出「類​​型不符:無法從布林值轉換為字串」

輸出:

Java 中的泛型是什麼?

如何透過泛型實作程式碼可重複使用?

現在,讓我們定義一個常規方法:

代碼:

public static void welcome(String name){
System.out.println("welcome to " + name);
}
登入後複製

此方法只能透過傳遞字串參數來呼叫。

代碼:

welcome("eduCBA");
登入後複製

其輸出將是「歡迎來到 eduCBA」

但是,只有 String 可以呼叫此方法。嘗試傳遞任何其他資料類型(例如整數或布林值)將導致編譯時錯誤,指出「Runner 類型中的方法welcome(String) 不適用於參數(布林值)」

輸出:

Java 中的泛型是什麼?

如果想要為不同的資料型別呼叫類似的方法,可以建立一個接受所需資料型別作為參數的新方法。這種以不同資料類型的參數重寫方法​​的技術稱為「方法重載」。然而,這種方法的一個缺點是它可能會導致更大的程式碼大小。

也可以使用泛型重寫上述方法,並將其用於我們需要的任何資料類型。

定義通用方法:

代碼:

public static <T> void welcome(T t){
System.out.println("it is " + t);
}
登入後複製

注意:這裡,「t」是類型T的物件。用於呼叫方法的實際資料類型將被指派給類型參數“T”。

這使得該方法可以根據需要與不同的資料類型重複使用,包括字串、布林值、整數等。

代碼:

welcome("educba");
Integer myint = 1;
welcome(myint);
welcome(true);
登入後複製

上述語句將提供以下輸出:

輸出:

it is educba
it is 1
it is true
登入後複製

因此,在這裡使用泛型,我們可以針對不同的資料類型重複使用我們的方法。

Java 中的泛型是什麼?

如何使用泛型實現型別安全?

數組和集合之間的主要區別之一是數組只能存儲同質數據,而集合可以存儲異質數據。換句話說,集合可以儲存任何類型的對象,包括使用者定義的資料類型。

注意:集合只能保存對象,包括使用者定義的資料類型,而不是原始資料類型。為了使用原始資料類型,集合使用包裝類別。

Now, let’s consider an ArrayList.

Code:

ArrayList myList = new ArrayList();
登入後複製

One can add elements of various data types, such as strings, integers, and doubles, to an ArrayList object.

Code:

myList.add("eduCBA");
myList.add(1);
myList.add(5.2);
登入後複製

On printing the ArrayList object, one can see that it contains the following values: [eduCBA, 1, 5.2].

Output:

Java 中的泛型是什麼?

To retrieve these values into variables, one needs to typecast them.

Code:

String someStr = (String)myList.get(0);
Integer someInt = (Integer)myList.get(1);
Double someFlt = (Double)myList.get(2);
登入後複製

If one does not typecast, it will prompt a compile-time error stating, “Type mismatch: cannot convert from Object to String”

Output:

Java 中的泛型是什麼?

Thus, one must typecast them to their respective types while retrieving the objects from the ArrayList. However, in real-time scenarios, an ArrayList can contain thousands of records, and manually typecasting every object may not be feasible. There is the risk of mistakenly typecasting an object to an incorrect data type. In such cases, a runtime error will occur, stating “Exception in thread “main” java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String at com.serviceClasess.Runner.main(Runner.java:43)”.

Java 中的泛型是什麼?

As there is no guarantee with regard to the type of data present inside a collection (in this case, ArrayList), they are considered unsafe to use with respect to type. Here, Generics play a role in providing type safety.

Using ArrayList with Generics:

Code:

ArrayList<String> myList = new ArrayList<String>();
登入後複製

The String type is specified inside the angular brackets “>” which means that this particular implementation of ArrayList can only hold String type data. If one tries to add another data type, it will simply throw a compile-time error. Here, the ArrayList has been made type-safe by eliminating its chances of adding a data type other than “String.”

Output:

Java 中的泛型是什麼?

Now, since one has specified the data type that is allowed to be added to the collection with the help of Generics, there is no need to typecast it while retrieving the data. One can simply retrieve the data by writing.

Code:

String someStr = myList.get(0);
登入後複製

Output:

Java 中的泛型是什麼?

How do Generics in Java make Work Easier?

  • It helps make the collections type safe and ensures the code does not fail at a later point due to any run time exception.
  • It saves the coder from having to typecast each object in the collection, which simplifies and speeds up the code development process.
  • Generics allow writing code in a way that can work with multiple data types.

What else to do with Generics in Java?

So far, we have seen how we can achieve type safety and code reusability with Generics.

In addition to type safety and code reusability, here are some other features that Generics can provide:

  • Bounded & Multiple Bounded Types
  • Type Wildcards

1. Bounded Type

In the case of a bounded type, the data type of a parameter is bounded to a particular range. The keyword “extends” helps achieve this.

For example, let’s consider a Generic class with a bounded type parameter that extends the ‘Runnable interface’:

Code:

class myGenericClass<T extends Runnable>{}
登入後複製

Now, while creating its object in another class:

Code:

myGenericClass<Thread> myGen = new myGenericClass<Thread>();
登入後複製

The above statement will execute perfectly without any errors. In the case of the bounded type, one can pass the same class type or its child class type. Also, one can bind the parameter type to an interface and pass its implementations when invoking it, as in the example above.

What happens if one uses any other type of parameter?

Code:

myGenericClass<Integer> myGen = new myGenericClass<Integer >();
登入後複製

In the above case, it will result in a compile-time error, stating “Bound mismatch: The type Integer is not a valid substitute for the typecast of the type myGenericClass

Output:

Java 中的泛型是什麼?

  • Multiple bounded types: In the case of multiple bounded types, one can bind the parameter data type to more than one type.

Example:

Code:

class myGeneric<T extends Number & Runnable>{}
登入後複製

In this case, one can pass any type that extends the Number class and implements the Runnable interface. However, when using multiple bounded types, a few things should be noted:

  • One cannot extend more than one class at a time.
  • One can extend any number of interfaces simultaneously, i.e., there is no limit for interfaces.
  • The class name should always come first, followed by the interface name. If not, it will result in a compile-time error.

2. Type Wildcards

The “?” (question mark) symbol represents Type Wildcards. It makes use of two main keywords:

  1. extends (to define upper bound)
  2. super (to define lower bounds).

Example:

Code:

ArrayList<? extends T> al
登入後複製

The ArrayList object “al” will hold any data of type T and all its subclasses.

Code:

ArrayList<? super T> al
登入後複製

The ArrayList object “al” will hold any data of type T and all its superclasses.

Advantages of Generics in Java

  • Flexibility: Generics allow the code to accommodate different data types with the help of Generic classes and methods.
  • Code Maintenance and Reusability: Due to Generic classes and methods, one need not rewrite the code in case of a change in requirements later, making the code easier to maintain and reuse.
  • Type Safety: Provides type safety to the collection framework by defining the data type the collection can hold beforehand; and eliminating any chances of failure at run time due to ClassCastException.
  • Eliminating the Need to Typecast: Since the data types being held by the collections are already determined, one need not typecast it at the time of retrieval. This reduces the code’s length and a coder’s effort.

Generics in Java Skills

  • To work with Generics, one should be proficient in the basics of Java.
  • One should understand how type checking and typecasting work. Thorough knowledge of other concepts such as method overloading, the relationship between parent and child classes, interfaces, and their implementations is necessary.
  • Also, it is crucial to understand the difference between primitive data types (system-defined data type) and objects (user-defined data type) when working with the collection framework.

Why use Generics in Java?

  • Using Generics makes the code more maintainable as it reduces the need to rewrite data type-specific code every time there is a change in requirements.
  • By using Generics bounded type, one can restrict the data type and, at the same time, provide flexibility to the code by defining its range.
  • Generics provide type safety, making the code less error-prone and less likely to fail at a later point.

Scope for Generics in Java

Generics scope is limited to compile time, i.e., the Generics concept is applicable only at compile time but not at run time.

Example:

Code:

ArrayList myList = new ArrayList<Integer>();
ArrayList myList = new ArrayList<Float>();
ArrayList myList = new ArrayList<Double>();
ArrayList myList = new ArrayList<Boolean>();
登入後複製

Here all the above four statements are the same. They will allow adding any type of data to the list object.

Conclusion

Generics renders coding easy for a coder. It diminishes the chances of encountering ClassCastException at run time by providing strong type-checking. Also, it eliminates the need for typecasting, which means less code needs to be written. It allows the development of Generic algorithms independent of the data type they are working with.

以上是Java 中的泛型是什麼?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板