1.通配符(重点)
1).为什么泛型中需要通配符:
在程序类中追加了泛型的定义后,避免了ClassCastException的问题,但是又会产生新的情况:参数的统一问题,以下代码将会产生参数不统一的错误:
所以我们需要可以接收所有泛型类型,但是又不能够让用户随意修改,这种情况就需要使用通配符“?”来处理
把方法定义为
public static void demo1(Myclass<?> temp)
{
System.out.println(temp.getX());
}
此时就可以正常请求:
class Myclass<T>
{
private T x;
public T getX (){
return x;
}
public void setX(T x)
{
this.x=x;
}
}
public class tongpeifu {
public static void main(String[] args) {
Myclass<Integer> myclass= new Myclass<>();
myclass.setX(111);
demo1(myclass);
}
public static void demo1(Myclass<?> temp)
{
System.out.println(temp.getX());
}
}
此时使用通配符"?"描述的是它可以接收任意类型,但是由于不确定类型,所以无法修改
结果:
2):在"?"的基础上又产生了两个子通配符:
1.? extends 类:设置泛型上限:
例如:? extends Number,表示只能够设置Number或其子类,例如:Integer、Double等;
2.? super 类:设置泛型下限:
例如:? super String,表示只能够设置String及其父类Object。
注意:上限可以用在声明,不能修改;而下限只能用在方法参数,可以修改内容!
可以参考:
java泛型中通配符的使用详解_zy丶秋水的博客-CSDN博客_java泛型通配符详解
2.泛型接口:(开发中会经常使用)
泛型除了可以定义在类中。也可以定义在接口里面,这种情况称为泛型接口:
范例:定义一个泛型接口
interface Mytest<T>{
public void fun(T t);
}
对于这个接口的实现子类有俩种做法:
1.在子类定义时继续使用泛型,如下
class Test1<T> implements Mytest<T>
{
@Override
public void fun(T t) {
System.out.println(t);
}
}
public class test {
public static void main(String[] args) {
Test1<String> t=new Test1<String>();
t.fun("明天会更好");
}
}
结果:
2.在子类实现接口时给出明确的具体类型,如下
class Test1 implements Mytest<String>
{
@Override
public void fun(String t) {
System.out.println(t);
}
}
public class test {
public static void main(String[] args) {
Test1 t=new Test1();
t.fun("明天会更好");
}
}
结果:
3.类型擦除
转自Java中泛型 类型擦除 - raindream - 博客园
Java泛型是 Java 1.5 版本才引进的概念,在这之前是没有泛型的概念的,但显然,泛型代码能够很好地和之前版本的代 码很好地兼容。 这是因为,泛型信息只存在于代码编译阶段,在进入 JVM 之前,与泛型相关的信息会被擦除掉,专业术语叫做类 型擦除,(Java 的泛型在编译器有效,在运行期被删除,也就是说所有泛型参数类型在编译后都会被清除掉),看下面一个列子,代码如下:
public class Foo {
public void listMethod(List<String> stringList){
}
public void listMethod(List<Integer> intList) {
}
}
代码很简单,看起来没什么问题,但是编译器却报出如下错误信息:
Method listMethod(List<String>) has the same erasure listMethod(List<E>) as another method in type Foo
此错误的意思是说listMethod(List<String>) 方法在编译时擦除类型后的方法是listMethod(List<E>),它与另外一个方法重复,也就是方法签名重复。反编译之后的方法代码如下:
public void listMethod(List list)
{
}
由此可得在jvm中Class都是List 。