在类定义的时候并不会设置方法的参数,或类中属性的具体类型,而是在使用的时候再定义。
(1)T代表一般类
(2)E代表Element,常用于类中属性
(3)K代表Key的意思
(4)V代表Value,通常与K一起配合使用
(5)S代表Subtype的意思
class MyClass{
T value1; // T为类型参数,用于指代任何类型
E caclue2;
}
调用:MyClass
泛型只允许接受类,所有基本数据类型必须使用包装类。
class MyClass{
private T value1;
private E value2;
public T getValue1() {
return value1;
}
public void setValue1(T value1) {
this.value1 = value1;
}
public E getValue2() {
return value2;
}
public void setValue2(E value2) {
this.value2 = value2;
}
}
public class Test3 {
public static void main(String[] args){
MyClass myClass1 = new MyClass<>();
myClass1.setValue1("*****");
myClass1.setValue2("##########");
System.out.println(myClass1.getValue1()+myClass1.getValue2());
MyClass myClass2 = new MyClass<>();
myClass2.setValue1(5);
myClass2.setValue2("33333");
System.out.println(myClass2.getValue1()+myClass2.getValue2());
}
}
输出结果为:
*****##########
533333
// 表示该方法为泛型方法,()里的T表示类型参数
public T MyMethod(T num){
System.out.println(num);
}
调用:直接用所属类对象调用即可。
(1)泛型可以单独定义泛型方法,即使所属类不是泛型类,也可以定义泛型方法。泛型类与泛型方法也可以同时存在。
(2)当泛型类与泛型方法共存时,泛型类中的类型参数与泛型方法中的类型参数没有关系,泛型方法始终以自己定义的类型参数为准。
(3)规范:泛型方法中的类型参数与泛型类中的类型参数不要同名。
class MyClass1{
public void print(T t){
System.out.println(t);
}
}
public class Test3 {
public static void main(String[] args){
MyClass1 myClass = new MyClass1();
myClass.print("#########");
myClass.print(5);
myClass.print(2.001);
}
}
输出结果为:
###### #
5
2.001
(1)?
用于方法中,表示参数可以接收任意类型的泛型类对象。
只能取得数据,一定不能设置值。(因为不知道设置什么类型的数据)
class Point{
private T value1;
public T getValue1() {
return value1;
}
public void setValue1(T value1) {
this.value1 = value1;
}
}
public class Test5 {
public static void main(String[] args){
Point point = new Point<>();
point.setValue1("*****");
print(point);
Point point1 = new Point<>();
point1.setValue1(123);
print(point1);
}
public static void print(Point point){
System.out.println(point.getValue1());
}
}
输出结果为:
------
123
(2)? extends 类
设置和取得泛型上限
只能取得类中属性值,不能修改值。(因为父类向子类的向下转型需要强转,由于具体子类不确定,所以无法向下转型)
class Point1{
private T value1;
public T getValue1() {
return value1;
}
public void setValue1(T value1) {
this.value1 = value1;
}
}
public class Test5 {
public static void main(String[] args){
Point point1 = new Point<>();
point1.setValue1(123);
print(point1);
Point point2 = new Point<>();
point2.setValue1(3.14);
print(point2);
}
public static void print(Point point){
System.out.println(point.getValue1());
}
}
输出结果为:
123
3.14
(3)? super 类
取得泛型下限,只能用于方法中
可以取得类中属性,也可以设置值。(因为子类到父类是自动的向上转型)
class Point2{
}
public class Test5 {
public static void main(String[] args){
Point point = new Point<>();
point.setValue1("******");
print(point);
}
public static void print(Point point){
System.out.println(point.getValue1());
}
}
输出结果为:
******
interface IInterface{
T test(T num); // T表示类型参数,表示泛型接口
}
实现泛型接口的两种方法:
(1)子类继续保留泛型 - 泛型子类
class IInterfaceImpl implements IInterface{
}
(2)子类给出具体类型
class IInterfaceImpl implements IInterface{
}
语法糖:仅存在于源码阶段,编译后就消失不见(泛型、自动拆装箱)。
(1)泛型信息仅存在于代码的编译阶段,进入JVM之前与泛型相关的信息会被擦除掉(类型擦除),即泛型类与普通类在java虚拟机中没有任何区别。
(2)泛型类进入JVM之前会进行泛型擦除,之前泛型类的类型参数若没有指定上限,会被擦除为Object类;
如果指定了上限,则擦成指定上限,即类型参数被替换为相应类型上限。