河南开元建设有限公司网站,ftp与wordpress,网站建设移动网络公司,什么是网络营销道德前言 
Java 泛型#xff08;generics#xff09;是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制#xff0c;该机制允许程序员在编译时检测到非法的类型。它允许在定义类、接口和方法时使用类型参数。这种技术使得在编译期间可以使用任何类型#xff0c;而…前言 
Java 泛型generics是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制该机制允许程序员在编译时检测到非法的类型。它允许在定义类、接口和方法时使用类型参数。这种技术使得在编译期间可以使用任何类型而不是仅限于特定的类型。这大大提高了代码的灵活性和可重用性。 
泛型的基本语法是在类、接口或方法名的后面加上尖括号 并在其中定义类型参数。例如 
public class BoxT {  private T t;  public void set(T t) {  this.t  t;  }  public T get() {  return t;  }  
} 
在上述代码中T 是一个类型参数可以代表任何类型。你可以在类的定义中使用 T 来表示泛型然后在方法中使用 T 来表示任何类型的对象。 
Java 泛型的特性 
类型参数 
在定义泛型类或方法时使用类型参数代替具体的类型。类型参数在使用前需要命名通常使用大写字母来表示。例如在上述的 Box 类中我们使用 T 作为类型参数。 
java 中泛型标记符 
E - Element (在集合中使用因为集合中存放的是元素)T - TypeJava 类K - Key键V - Value值N - Number数值类型 - 表示不确定的 java 类型 
类型限定 
Java 泛型的类型参数有限制不能是 void、boolean、char、byte、short、int、float、double等原始类型。此外Java 泛型的类型参数只能是类类型包括 Class、接口类型或枚举类型不能是数组类型或函数类型。 
通配符类型参数 
除了具体类型作为类型参数外Java 泛型还支持通配符类型参数。通配符类型参数表示可以接受任何类型的参数例如 List? 表示可以接受任何类型的 List。通配符类型参数还有两种限定符 
? extends T表示该泛型只能接受 T 或 T 的子类。例如List? extends Number 可以接受 ListNumber、ListInteger 等但不能接受 ListString。  ? super T表示该泛型可以接受任何父类或等于 T 的类型。例如List? super Number 可以接受 ListNumber、ListObject 等但不能接受 ListString。 
泛型方法 
除了泛型类外还可以定义泛型方法。泛型方法允许在方法的返回值和参数类型中使用类型参数。例如 
public T T getFirst(ListT list) {  return list.get(0);  
} 
在上述代码中我们定义了一个泛型方法 getFirst它接受一个 ListT 类型的参数并返回一个 T 类型的对象。 
泛型继承 
当一个类继承一个泛型类时子类可以选择是否继续使用父类的类型参数。例如 
public class MyBox extends BoxInteger {  // ...  
} 
在上述代码中我们定义了一个子类 MyBox它继承了 BoxInteger 类。这样在 MyBox 类中我们可以直接使用 Integer 作为类型参数而不必重新定义一个新的类型参数。 
类型擦除 
Java 泛型的类型信息在编译后的代码中会被擦除只剩下原始类型的信息。这是为了保持 Java 代码的兼容性和跨平台性。因此在使用泛型时不能在运行时通过反射来获取泛型的具体类型信息。 
以下是一个简单代码示例演示了类型擦除的概念  
public class MyClassT {// 定义一个泛型类MyClass其中T是一个类型参数private T value; // 定义一个私有成员变量value它的类型是泛型参数Tpublic MyClass(T value) { // 定义一个构造函数接受一个类型为T的参数this.value  value; // 将参数值赋值给成员变量value}public T getValue() { // 定义一个公共方法getValue返回类型为T的值return value; // 返回成员变量value的值}public static void main(String[] args) {// 创建两个不同类型的实例MyClassInteger intExample  new MyClass(123); // 创建一个Integer类型的MyClass实例并将其引用赋给intExample变量MyClassString stringExample  new MyClass(Hello); // 创建一个String类型的MyClass实例并将其引用赋给stringExample变量// 调用getValue方法并打印结果System.out.println(intExample.getValue()); // 调用intExample的getValue方法并打印返回值输出123System.out.println(stringExample.getValue()); // 调用stringExample的getValue方法并打印返回值输出Hello}
} 
有界类型参数 
Java 泛型还支持有界类型参数。有界类型参数允许在定义泛型类或方法时对类型参数进行限制。例如 
public class MyListT extends Number {  private ListT list;  // ...  
} 
在上述代码中我们定义了一个泛型类 MyList其中的类型参数 T 必须是 Number 或其子类。这样在使用 MyList 时只能使用符合这个条件的类型作为类型参数。 
使用泛型的注意事项 
泛型不能使用基本类型如int、float等必须使用其包装类如Integer、Float等。运行时类型检查。Java的泛型是通过类型擦除实现的在运行时类型检查被擦除因此运行时可能抛出异常。对于有界类型参数子类不能继承父类并改变类型参数的限定范围。例如如果父类中的类型参数限定为某个类子类中的类型参数必须是这个类的子类或者相同。不能使用泛型数组如ArrayListT[]。不能使用泛型构造对象如T t  new T();。在静态方法中使用泛型泛型变量不可以使用static关键字来修饰。不可以使用泛型类继承Exception类即泛型类不可以作为异常被抛出。对于equals方法如果使用泛型类可能会出现类型转换异常因此需要重写equals方法。如果某个泛型类还有同名的非泛型类不要混合使用坚持使用泛型类。泛型的推断。如果泛型的限定类型已经确定可以使用泛型的推断即直接使用变量类型作为限定类型不需要再写出限定类型。 
实例 
import java.util.ArrayList;
import java.util.List;// 定义一个泛型类 User使用通配符类型参数
class UserT {// 定义一个存储对象引用的列表其中T代表任意类型ListT friends;// 构造函数初始化朋友列表public User() {this.friends  new ArrayList();}// 泛型方法接受一个类型为T的参数并返回一个类型为T的对象public T getLastFriend() {// 返回列表中的最后一个朋友如果列表为空则返回nullif (friends.isEmpty()) {return null;} else {return friends.get(friends.size() - 1);}}// 重写toString方法用于打印用户和朋友列表Overridepublic String toString() {return User{ friends  friends };}
}// 定义一个子类 StringUser继承自泛型类 User并指定类型参数为 String
class StringUser extends UserString {// 重写父类的toString方法只打印字符串类型的朋友列表Overridepublic String toString() {return StringUser{ friends  friends };}
}// 主类测试以上定义的泛型类和子类
public class MyClass {public static void main(String[] args) {// 创建一个 UserString 对象存储字符串类型的朋友UserString user  new User();((UserString) user).friends.add(Alice);((UserString) user).friends.add(Bob);System.out.println(user); // 输出User{friends[Alice, Bob]}System.out.println(user.getLastFriend()); // 输出Bob// 创建一个 StringUser 对象同样存储字符串类型的朋友StringUser stringUser  new StringUser();stringUser.friends.add(Charlie);stringUser.friends.add(Dave);System.out.println(stringUser); // 输出StringUser{friends[Charlie, Dave]}System.out.println(stringUser.getLastFriend()); // 输出Dave}
} 
代码解释 
UserT 是一个泛型类其中 T 是类型参数。这意味着可以创建 UserString, UserInteger, UserObject 等不同类型的用户对象。这个类有一个通配符类型参数 T这意味着可以使用任意类型来创建用户对象。getLastFriend() 方法是一个泛型方法它接受一个类型为 T 的参数并返回一个类型为 T 的对象。这个方法从朋友列表中返回最后一个朋友。如果列表为空则返回 null。注意由于类型擦除Java在运行时并不保留泛型的具体类型信息。因此不能在运行时知道 T 的具体类型。然而这并不影响使用泛型。StringUser 是 UserString 的子类。可以使用有界类型参数来继承泛型类并指定具体的类型。在这种情况下StringUser 只可以存储字符串类型的朋友。由于子类中没有重写 getLastFriend() 方法它将使用父类的实现。但是我们在 StringUser 中重写了 toString() 方法以只打印字符串类型的朋友列表。在 MyClass 类中我们创建了一个 UserString 对象和一个 StringUser 对象。我们可以看到尽管运行时不知道泛型的具体类型由于类型擦除但是我们仍然可以创建不同类型的用户对象。此外由于有界类型参数StringUser 只可以存储字符串类型的朋友。