您的位置:首页 > 编程语言 > Java开发

java里程碑之泛型--泛型基本语法

2015-10-20 10:10 441 查看
1,java7提供的泛型菱形语法

在java7之前,如果使用带泛型的接口和类定义变量初始化对象的时候,构造器后面也必须带上泛型,这有点恶心的。以前我在公司一直使用的java6,所以我也已经习惯了这种写法。代码如下:

List<String> list = new ArrayList<String>();
Map<String, String> map = new HashMap<String, String>();
为了绕开这么恶心的写法,我都习惯用google的common包了。代码如下:

List<String> list = Lists.newArrayList();
Map<String, String> map = Maps.newHashMap();
在java7之后,java允许在构造器后不需要带完整的泛型信息,只要给出一对尖括号就可以,具体的java可以推断出应该是什么泛型信息,上面的代码可以做如下修改:

List<String> list = new ArrayList<>();
Map<String, String> map = new HashMap<>();
上面的代码对原来的泛型并没有任何改变,只是更好的简化了泛型编程。

2,定义泛型接口和类

关于集合使用泛型,这里就不做赘述了。我们可以为任何接口和类增加泛型申明。下面定义一个Test泛型类:

public class Test<T>
{
//实例属性中可以使用泛型T
private T name;

//定义构造器可以使用泛型T
public Test()
{

}

public Test(T name)
{
this.name = name;
}

public T getName()
{
return name;
}

public void setName(T name)
{
this.name = name;
}

public static void main(String[] args)
{
//初始化实例的时候构造器后面的尖括号可以省略
Test<String> test1 = new Test<>();
test1.setName("LinkinPark...");
System.out.println(test1.getName());
Test<Integer> test2 = new Test<>();
}

}


注意:当创建带泛型声明的自定义类时,为该类定义构造器时,构造器还是原来的类名,不可以增加泛型申明。比如说为Test<T>类定义构造器,其构造器名依然是Test,不是Apple<T>。



3,从泛型类派生子类

当创建了带泛型声明的接口和类之后,可以为该接口创建实现类,或从该父类派生子类,需要指出的是,当使用这些接口和父类的时候不能还是泛型形参了。比如,下面的代码报错。

class Test1 extends Test<T>
{
}


如果想从一个接口或者父类派生子类的话,我们应该为T的泛型形参传入实际的类型。正确的写法如下:

class Test1 extends Test<String>
{
}


值得注意的2点:

1,如上面的代码Test1类中,我们继承了Test<String>类,Test中所有使用T类型形参的地方都被替换成了String类型,Test类中原来所有的方法的形参也都变成了具体的类型了。我们在重写父类的方法的时候要特别注意这一点。

比如原来的Test类中有一个方法是:

public T getName()
{
}
我们在重写这个方法时候应该写成

public String getName()
{
}


2,调用方法的时候必须为所有的数据形参传入参数值,和调用方法不同,使用类和接口的时候可以不为类型形参T传入实际的类型参数,这个时候我们就不能写上泛型T标示符了。比如下面的代码也是正确的:

class Test1 extends Test
{

}


如果没有为泛型T传入实际的类型参数,Java编译器会发出警告,使用了未经检查或者不安全的操作。此时系统会把类里面的泛型T当做Object来处理。这种写法实际上就是说没有用泛型,实际编码过程中要尽量绕开这种写法。就个人经验而言,每次我看到那个黄色警告的时候都会想办法消除掉,最土的做法就是加注解来抑制警告@SuppressWarnings("rawtypes")。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: