jvm泛型擦除_什么是泛型「建议收藏」

jvm泛型擦除_什么是泛型「建议收藏」泛型,一个孤独的守门者

泛型,一个孤独的守门者。

大家可能会有疑问,我为什么叫做泛型是一个守门者。这其实是我个人的看法而已,我的意思是说泛型没有其看起来那么深不可测,它并不神秘与神奇。泛型是 Java 中一个很小巧的概念,但同时也是一个很容易让人迷惑的知识点,它让人迷惑的地方在于它的许多表现有点违反直觉。

文章开始的地方,先给大家奉上一道经典的测试题。

List<String> l1 = new ArrayList<String>();
List<Integer> l2 = new ArrayList<Integer>();
		
System.out.println(l1.getClass() == l2.getClass());

请问,上面代码最终结果输出的是什么?不了解泛型的和很熟悉泛型的同学应该能够答出来,而对泛型有所了解,但是了解不深入的同学可能会答错。

正确答案是 true。

上面的代码中涉及到了泛型,而输出的结果缘由是类型擦除。先好好说说泛型。

泛型是什么?

泛型的英文是 generics,generic 的意思是通用,而翻译成中文,泛应该意为广泛,型是类型。所以泛型就是能广泛适用的类型。

但泛型还有一种较为准确的说法就是为了参数化类型,或者说可以将类型当作参数传递给一个类或者是方法。

那么,如何解释类型参数化呢?

public class Cache { 
   
	Object value;

	public Object getValue() { 
   
		return value;
	}

	public void setValue(Object value) { 
   
		this.value = value;
	}
	
}

假设 Cache 能够存取任何类型的值,于是,我们可以这样使用它。

Cache cache = new Cache();
cache.setValue(134);
int value = (int) cache.getValue();
cache.setValue("hello");
String value1 = (String) cache.getValue();

使用的方法也很简单,只要我们做正确的强制转换就好了。

但是,泛型却给我们带来了不一样的编程体验。

public class Cache<T> { 
   
	T value;

	public Object getValue() { 
   
		return value;
	}

	public void setValue(T value) { 
   
		this.value = value;
	}
	
}

这就是泛型,它将 value 这个属性的类型也参数化了,这就是所谓的参数化类型。再看它的使用方法。

Cache<String> cache1 = new Cache<String>();
cache1.setValue("123");
String value2 = cache1.getValue();
		
Cache<Integer> cache2 = new Cache<Integer>();
cache2.setValue(456);
int value3 = cache2.getValue();

最显而易见的好处就是它不再需要对取出来的结果进行强制转换了。但,还有另外一点不同。
这里写图片描述
泛型除了可以将类型参数化外,而参数一旦确定好,如果类似不匹配,编译器就不通过。
上面代码显示,无法将一个 String 对象设置到 cache2 中,因为泛型让它只接受 Integer 的类型。

所以,综合上面信息,我们可以得到下面的结论。

  1. 与普通的 Object 代替一切类型这样简单粗暴而言,泛型使得数据的类别可以像参数一样由外部传递进来。它提供了一种扩展能力。它更符合面向抽象开发的软件编程宗旨。
  2. 当具体的类型确定后,泛型又提供了一种类型检测的机制,只有相匹配的数据才能正常的赋值,否则编译器就不通过。所以说,它是一种类型安全检测机制,一定程度上提高了软件的安全性防止出现低级的失误。
  3. 泛型提高了程序代码的可读性,不必要等到运行的时候才去强制转换,在定义或者实例化阶段,因为 Cache<String>这个类型显化的效果,程序员能够一目了然猜测出代码要操作的数据类型。

下面的文章,我们正常介绍泛型的相关知识。

泛型的定义和使用

泛型按照使用情况可以分为 3 种。

  1. 泛型类。
  2. 泛型方法。
  3. 泛型接口。

泛型类

我们可以这样定义一个泛型类。

public class Test<T> { 
   
	T field1;
}

尖括号 <>中的 T 被称作是类型参数,用于指代任何类型。事实上,T 只是一种习惯性写法,如果你愿意。你可以这样写。

public class Test<Hello> { 
   
	Hello field1;
}

但出于规范的目的,Java 还是建议我们用单个大写字母来代表类型参数。常见的如:

  1. T 代表一般的任何类。
  2. E 代表 Element 的意思,或者 Exception 异常的意思。
  3. K 代表 Key 的意思。
  4. V 代表 Value 的意思,通常与 K 一起配合使用。
  5. S 代表 Subtype 的意思,文章后面部分会讲解示意。

如果一个类被 <T>的形式定义,那么它就被称为是泛型类。

那么对于泛型类怎么样使用呢?

Test<String> test1 = new Test<>();
Test<Integer>

今天的文章jvm泛型擦除_什么是泛型「建议收藏」分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/71272.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注