Java 中的泛型是一项高级功能,可实现代码可重用性和类型安全。代码可重用性功能是通过定义通用类、接口、构造函数和方法来实现的。泛型使用数据类型声明来确保类型安全,从而消除运行时错误的机会。尖括号“”符号用于实现泛型,类型参数在括号内定义。这些类型参数包括“T”(类型)、“E”(元素)、“N”(数字)、“K”(键)和“V”(值)。具有类型 T 参数的泛型类的示例是“public class DemoGenericClass
开始您的免费软件开发课程
网络开发、编程语言、软件测试及其他
泛型是使用尖括号“”实现的括号内包含类型参数“T”。例如,在
泛型类可以定义为:
代码:
public class MyGenericClass<T> {…}
以下是标准类型参数:
多参数的情况下,用S、U、V等分别定义第二个、第三个、第四个参数。
什么是类型安全以及它如何工作?泛型类、接口、构造函数和方法与我们的常规类和方法有何不同,从而使它们可重用?
Java 是一种静态类型语言,在使用变量之前需要声明其数据类型。
示例:
代码:
String myString ="eduCBA";
在上面的代码中,“String”是数据类型,“myString”是保存 String 类型值的变量。
现在,如果尝试传递一个布尔值来代替字符串,如下所示:
代码:
String myBooleanStr = true;
它将立即导致编译时错误,指出“类型不匹配:无法从布尔值转换为字符串”
输出:
现在,让我们定义一个常规方法:
代码:
public static void welcome(String name){ System.out.println("welcome to " + name); }
该方法只能通过传递字符串参数来调用。
代码:
welcome("eduCBA");
其输出将是“欢迎来到 eduCBA”
但是,只有 String 可以调用此方法。尝试传递任何其他数据类型(例如整数或布尔值)将导致编译时错误,指出“Runner 类型中的方法welcome(String) 不适用于参数(布尔值)”
输出:
如果想要为不同的数据类型调用类似的方法,可以创建一个接受所需数据类型作为参数的新方法。这种用不同数据类型的参数重写方法的技术称为“方法重载”。然而,这种方法的一个缺点是它可能会导致更大的代码大小。
还可以使用泛型重写上述方法,并将其用于我们需要的任何数据类型。
定义通用方法:
代码:
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
因此,在这里使用泛型,我们可以针对不同的数据类型重用我们的方法。
数组和集合之间的主要区别之一是数组只能存储同质数据,而集合可以存储异构数据。换句话说,集合可以存储任何类型的对象,包括用户定义的数据类型。
注意:集合只能保存对象,包括用户定义的数据类型,而不是原始数据类型。为了使用原始数据类型,集合使用包装类。
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:
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:
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)”.
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.
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:
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:
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:
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
Output:
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:
The “?” (question mark) symbol represents Type Wildcards. It makes use of two main keywords:
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.
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.
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中文网其他相关文章!