java generics
1. Introduction to Generics
## Generics are a new feature of Java SE 1.5. The essence of generics isparameterized types , that is to say, the data type being operated on is specified as a parameter. Before Java SE 1.5, without generics, the "arbitrary" parameters were implemented by referencing the type Object. The disadvantage of "arbitrary" was that explicit
mandatory Type conversion, and this conversion requires the developer to know the actual parameter type beforehand. In the case of forced type conversion errors, the compiler may not prompt an error , and the exception will only occur when runs . This is a security risk. The advantage of generics is that type safety is checked at compile time, and all casts are automatic and implicit to improve code reuse.
There is no error:

"java.lang.classCastException"

private transient Object[] elementData; , using get() returns An Object object needs
forced conversion, but an Integer value is mixed in the middle, causing the forced conversion to fail. This error is caused by the arbitrary of Object. If you can find that the data type is wrong during the compilation stage, it will be very convenient.
Generics meets this requirement: I will modify this program. ArrayList uses generics: you will find that during the compilation stage An error was reported. 
Do not use generics:
package com.chb.fanxing;public class NoGen {
private Object ob;
public NoGen(Object ob) {
this.ob = ob;
}
getter setter...
private void showType() {
System.out.println("数据的实际类型是:" + ob.getClass().getName());
} public static void main(String[] args) {
NoGen ngInt = new NoGen(88);
ngInt.showType(); int i = (int)ngInt.getOb();
System.out.println("value = " + i);
System.out.println("---------------");
NoGen ngStr = new NoGen("88");
ngStr.showType();
String str = (String)ngStr.getOb();
System.out.println("value = " + str);
}
}Use Generics:
package com.chb.fanxing;public class Gen<T> {
private T ob;
public Gen(T ob) {
this.ob = ob;
}
getter setter...
private void showType() {
System.out.println("T的实际类型:"+ob.getClass().getName());
} public static void main(String[] args) { //定义一个Integer版本
Gen<Integer> genInt = new Gen<Integer>(88);
genInt.showType(); int i = genInt.getOb();//此处不用强制转换
System.out.println("value = " + i);
System.out.println("----------------------");
Gen<String> genStr = new Gen<String>("88");
genStr.showType();
String str = genStr.getOb();
System.out.println("value = "+str);
}
} Running results: The running results of the two examples are consistent
数据的实际类型是:java.lang.Integervalue = 88 ---------------数据的实际类型是:java.lang.String value = 88Comparing the two examples, you will find :
- Use generics, forced conversion is performed automatically:
int i = genInt.getOb();//此处不用强制转换
- Without using generics, you must To perform manual forced conversion
int i = (int)ngInt.getOb();3. In-depth generics3.1. There are two classes, and we need to print their member variables
class StringDemo {
private String s;
public StringDemo (String s) {
this.s = s;
}
setter geter....
}
class DoubleDemo{
private Double d;
public DoubleDemo(Double d) {
this.d = d;
}
setter getter...
}
3.2. Refactoring Carefully observe that the functions of the two classes are basically the same, but the data types are different. Considering the refactoring, because Object is the base class of all classes, you can use Object as a member variable, so that the code It can be generally used. The refactored code is as follows:
class ObjectDemo{
private Object ob;
public ObjectDemo(Object ob){
this.ob = ob;
}
setter getter...
}ObjectDemo test: public static void ObjectDemoTest(){
ObjectDemo strOD = new ObjectDemo("123");
ObjectDemo dOD = new ObjectDemo(new Double(23));
ObjectDemo od = new ObjectDemo(new Object());
System.out.println((String)strOD.getOb());
System.out.println((Double)dOD.getOb());
System.out.println(od.getOb());
} Running results: 
Force conversion must be used in the above ObjectDemoTest(), which is more troublesome. We must also know the data type to be converted in advance in order to perform the correct conversion , otherwise, an error will occur. There will be no problem when the business is compiled, but once it is run, a "classCastException" will appear. So we don't need to do the cast ourselves, which is especially important for generics.
class GenDemo<T>{
private T t;
public GenDemo(T t) {
this.t = t;
}
public void setT(T t) {
this.t = t;
}
public T getT() {
return t;
}
} Test: Eliminates manual cast
public static void GenTest() {
GenDemo<String> strOD = new GenDemo<String>("123");
GenDemo<Double> dOD = new GenDemo<Double>(new Double(23));
GenDemo<Object> od = new GenDemo<Object>(new Object());
System.out.println(strOD.getT());
System.out.println(dOD.getT());
System.out.println(od.getT());
} Let’s explain the above generic syntax: Use to represent a type holding The name is equivalent to a formal parameter. The type of data is determined by the type of the actual data passed in, and then T is used as the type of the return value of the member, parameter, and method. T is just a name, you can choose it at will.
class GenDemo, T does not impose any restrictions, and is actually equivalent to Object,
is equivalent to class GenDemo.
Compared with Object, classes defined using generics can use
< Double> dOD = new GenDemo
Restricted generics
Multiple interface restrictions
Wildcard generics
一、泛型简介
泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。
泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,以提高代码的重用率。
二、为什么需要泛型
2.1、编译期对数据类型进行检测
首先我们看一个案例,向一个ArrayList中添加字符串,“不小心”添加了整数,如下面代码,
并没有错误:

但是执行时,会报错:“java.lang.classCastException”

因为ArrayList中维护的是一个Object数组, private transient Object[] elementData;
, 使用get()返回的是一个Object对象, 需要强制转换,但是中间混杂一个Integer数值, 导致强制转换失败。这个错误就是由于Object的任意化导致的。
如果能在编译阶段就发现数据类型有错, 那么就很方便,泛型就满足了这个要求:我将这个程序修改一下,ArrayList使用泛型:会发现编译阶段就报错了. 
2.2强制转换是自动的
不使用泛型:
package com.chb.fanxing;public class NoGen {
private Object ob;
public NoGen(Object ob) {
this.ob = ob;
}
getter setter... private void showType() {
System.out.println("数据的实际类型是:" + ob.getClass().getName());
} public static void main(String[] args) {
NoGen ngInt = new NoGen(88);
ngInt.showType(); int i = (int)ngInt.getOb();
System.out.println("value = " + i);
System.out.println("---------------");
NoGen ngStr = new NoGen("88");
ngStr.showType();
String str = (String)ngStr.getOb();
System.out.println("value = " + str);
}
}使用泛型:
package com.chb.fanxing;public class Gen<T> {
private T ob;
public Gen(T ob) {
this.ob = ob;
}
getter setter... private void showType() {
System.out.println("T的实际类型:"+ob.getClass().getName());
} public static void main(String[] args) { //定义一个Integer版本
Gen<Integer> genInt = new Gen<Integer>(88);
genInt.showType(); int i = genInt.getOb();//此处不用强制转换
System.out.println("value = " + i);
System.out.println("----------------------");
Gen<String> genStr = new Gen<String>("88");
genStr.showType();
String str = genStr.getOb();
System.out.println("value = "+str);
}
}运行结果:
两个例子的运行结果是一致的
数据的实际类型是:java.lang.Integervalue = 88 ---------------数据的实际类型是:java.lang.String value = 88
对比两个例子会发现:
使用泛型,强制转换时自动进行的:
int i = genInt.getOb();//此处不用强制转换
而不使用泛型,必须要进行手动强制转化
int i = (int)ngInt.getOb();
三、深入泛型
3.1 、有两个类,我们需要打印他们的成员变量
class StringDemo {
private String s;
public StringDemo (String s) {
this.s = s;
}
setter geter....
}
class DoubleDemo{
private Double d;
public DoubleDemo(Double d) {
this.d = d;
}
setter getter...
}3.2、重构
仔细观察两个类功能基本一致,只是数据类型不一样,考虑到重构,因为Object是所有类的基类,所以可以使用Object作为成员变量,这样代码就可以通用了。重构代码如下:
class ObjectDemo{
private Object ob;
public ObjectDemo(Object ob){
this.ob = ob;
}
setter getter...
}ObjectDemo测试:
public static void ObjectDemoTest(){
ObjectDemo strOD = new ObjectDemo("123");
ObjectDemo dOD = new ObjectDemo(new Double(23));
ObjectDemo od = new ObjectDemo(new Object());
System.out.println((String)strOD.getOb());
System.out.println((Double)dOD.getOb());
System.out.println(od.getOb());
}运行结果: 
3.3使用泛型重构
发现上面的ObjectDemoTest() 中必须要使用强制转换,这比较麻烦,我们还必须事先知道要转换的数据类型,才能进行正确的转换,否则,会出现错误, 业务编译时没有问题,但是一运行,会出现”classCastException”。所以我们需要不用自己进行强制转换,这是泛型就尤为重要。
class GenDemo<T>{ private T t; public GenDemo(T t) { this.t = t;
}
public void setT(T t) { this.t = t;
} public T getT() { return t;
}
}测试:省去了手动进行强制转换
public static void GenTest() {
GenDemo<String> strOD = new GenDemo<String>("123");
GenDemo<Double> dOD = new GenDemo<Double>(new Double(23));
GenDemo<Object> od = new GenDemo<Object>(new Object());
System.out.println(strOD.getT());
System.out.println(dOD.getT());
System.out.println(od.getT());
}
下面解释一下上面的泛型语法:
使用表示一个类型持有者名称, 相当于一个形参,数据的类型是有实际传入的数据的类型决定,然后T作为成员、参数、方法的返回值的类型。
T仅仅是一个名字,可以随意取的。
class GenDemo , T没有进行任何限制, 实际相当于 Object,
等同于 class GenDemo。
与Object相比,使用泛型所定义的类,在定义和声明,可以使用来制定真实的数据类型,如:
GenDemo
也可以不指定,那么就需要进行强制转换。
以上就是java之泛型的内容,更多相关内容请关注PHP中文网(m.sbmmt.com)!
Hot AI Tools
Undress AI Tool
Undress images for free
Undresser.AI Undress
AI-powered app for creating realistic nude photos
AI Clothes Remover
Online AI tool for removing clothes from photos.
Clothoff.io
AI clothes remover
Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!
Hot Article
Hot Tools
Notepad++7.3.1
Easy-to-use and free code editor
SublimeText3 Chinese version
Chinese version, very easy to use
Zend Studio 13.0.1
Powerful PHP integrated development environment
Dreamweaver CS6
Visual web development tools
SublimeText3 Mac version
God-level code editing software (SublimeText3)
What is a deadlock in Java and how can you prevent it?
Aug 23, 2025 pm 12:55 PM
AdeadlockinJavaoccurswhentwoormorethreadsareblockedforever,eachwaitingforaresourceheldbytheother,typicallyduetocircularwaitcausedbyinconsistentlockordering;thiscanbepreventedbybreakingoneofthefournecessaryconditions—mutualexclusion,holdandwait,nopree
How to use Optional in Java?
Aug 22, 2025 am 10:27 AM
UseOptional.empty(),Optional.of(),andOptional.ofNullable()tocreateOptionalinstancesdependingonwhetherthevalueisabsent,non-null,orpossiblynull.2.CheckforvaluessafelyusingisPresent()orpreferablyifPresent()toavoiddirectnullchecks.3.Providedefaultswithor
Java Persistence with Spring Data JPA and Hibernate
Aug 22, 2025 am 07:52 AM
The core of SpringDataJPA and Hibernate working together is: 1. JPA is the specification and Hibernate is the implementation, SpringDataJPA encapsulation simplifies DAO development; 2. Entity classes map database structures through @Entity, @Id, @Column, etc.; 3. Repository interface inherits JpaRepository to automatically implement CRUD and named query methods; 4. Complex queries use @Query annotation to support JPQL or native SQL; 5. In SpringBoot, integration is completed by adding starter dependencies and configuring data sources and JPA attributes; 6. Transactions are made by @Transactiona
Java Cryptography Architecture (JCA) for Secure Coding
Aug 23, 2025 pm 01:20 PM
Understand JCA core components such as MessageDigest, Cipher, KeyGenerator, SecureRandom, Signature, KeyStore, etc., which implement algorithms through the provider mechanism; 2. Use strong algorithms and parameters such as SHA-256/SHA-512, AES (256-bit key, GCM mode), RSA (2048-bit or above) and SecureRandom; 3. Avoid hard-coded keys, use KeyStore to manage keys, and generate keys through securely derived passwords such as PBKDF2; 4. Disable ECB mode, adopt authentication encryption modes such as GCM, use unique random IVs for each encryption, and clear sensitive ones in time
LOL Game Settings Not Saving After Closing [FIXED]
Aug 24, 2025 am 03:17 AM
IfLeagueofLegendssettingsaren’tsaving,trythesesteps:1.Runthegameasadministrator.2.GrantfullfolderpermissionstotheLeagueofLegendsdirectory.3.Editandensuregame.cfgisn’tread-only.4.Disablecloudsyncforthegamefolder.5.RepairthegameviatheRiotClient.
How to use the Pattern and Matcher classes in Java?
Aug 22, 2025 am 09:57 AM
The Pattern class is used to compile regular expressions, and the Matcher class is used to perform matching operations on strings. The combination of the two can realize text search, matching and replacement; first create a pattern object through Pattern.compile(), and then call its matcher() method to generate a Matcher instance. Then use matches() to judge the full string matching, find() to find subsequences, replaceAll() or replaceFirst() for replacement. If the regular contains a capture group, the nth group content can be obtained through group(n). In actual applications, you should avoid repeated compilation patterns, pay attention to special character escapes, and use the matching pattern flag as needed, and ultimately achieve efficient
Edit bookmarks in chrome
Aug 27, 2025 am 12:03 AM
Chrome bookmark editing is simple and practical. Users can enter the bookmark manager through the shortcut keys Ctrl Shift O (Windows) or Cmd Shift O (Mac), or enter through the browser menu; 1. When editing a single bookmark, right-click to select "Edit", modify the title or URL and click "Finish" to save; 2. When organizing bookmarks in batches, you can hold Ctrl (or Cmd) to multiple-choice bookmarks in the bookmark manager, right-click to select "Move to" or "Copy to" the target folder; 3. When exporting and importing bookmarks, click the "Solve" button to select "Export Bookmark" to save as HTML file, and then restore it through the "Import Bookmark" function if necessary.
'Java is not recognized' Error in CMD [3 Simple Steps]
Aug 23, 2025 am 01:50 AM
IfJavaisnotrecognizedinCMD,ensureJavaisinstalled,settheJAVA_HOMEvariabletotheJDKpath,andaddtheJDK'sbinfoldertothesystemPATH.RestartCMDandrunjava-versiontoconfirm.


