最近在看android框架源码中,看到很多使用了
<具体类名称>或者
<T>
<E>
<符号>
...
这些格式的代码
凡是代码使用了
<xxx>
这个格式,那么别多想了,一定是使用了泛型。。。
看了一篇不错的文章:
http://www.cnblogs.com/lwbqqyumidi/p/3837629.html
学习总结:
1、
使用其实只要2中
T 某个具体泛型 类
? 所有泛型 类
使用格式主要:
new 类名<xxx>
class 类<xxx>
interface 名称<xxx>
参数 T t;
方法 public T getName(){
...
return T;
}
在创建类的时候指定了泛型,和创建的类没有半毛钱关系,
public class Studnet<T>{
...
}
上面代码,T和Student没有直接关系。
在student类中,
可能有方法返回类型是 T,
参数类型是 T,
也可能根本没有使用T。
如果出现T,那么所有的T都是一样的,同一个类型!!!
public class Student<T> {
T id;//
int age;
public Student(T id, int age) {//T
super();
this.id = id;
this.age = age;
}
public Student(T id) {
// TODO Auto-generated constructor stub
this.id = id;
}
public T getId() {
return id;
}
public void setId(T id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
测试:
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Student s;
Student<Integer> student = new Student();
//指定了T是Integer
student.setId("1");
/*出错,
The method setId(Integer) in the type Student<Integer> is not applicable for the arguments (String)
*/
}
}
正确写法:
Student<Integer> student = new Student();
student.setId(100);
要是我同时指定id 是 int 或者double、float ,更牛逼的是id可以是任何类型,怎么办啊????
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Student<String> student0 = new Student();
student0.setId("123");
Student<Integer> student1 = new Student();
student1.setId(123);
Student<Double> student2 = new Student();
student2.setId(123d);
Student<Float> student3 = new Student();
student3.setId(123f);
student0.getId();
student1.getId();
student2.getId();
student3.getId();
}
}
比如,4种类型,那我就要写4个getId( );
这也太麻烦了吧。。。
答案就是泛型通配符!!!
简化:
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Student<String> student0 = new Student();
student0.setId("123");
getStuId(student0);
//
Student<Integer> student1 = new Student();
student1.setId(123);
getStuId(student1);
//
Student<Double> student2 = new Student();
student2.setId(123d);
getStuId(student2);
//
Student<Float> student3 = new Student();
student3.setId(123f);
getStuId(student3);
}
private static void getStuId(Student<?> student) {
System.out.println(student.getId().getClass());
}
}
打印:
class java.lang.String
class java.lang.Integer
class java.lang.Double
class java.lang.Float
Student<?> student 这个对象可以理解成是
所有具体泛型对象的 父类!!!!!!!!!!!!!!!!!
貌似只能在方法参数中使用????????????
类型通配符一般是使用 ? 代替具体的类型实参。注意了,此处是类型实参,而不是类型形参!
如果你想过滤一下通配符代表的类
使用
<? extends xxxx类>
private static void getStuId(Student<? extends Number> student) {。。。}
这个时候
Student<String> student0 = new Student();
student0.setId("123");
getStuId(student0);
报错
The method getStuId(Student<? extends Number>) in the type Test is not applicable for the arguments (Student<String>)
扩展
泛型不支持数组
//Cannot create a generic array of Student<String>
Student<String>[] stuArray=new Student<String>[100];
修改:
Student<Integer>[] stuArray=new Student[100];
stuArray[0].setId(123);//必须是Integer
这里你可能会想,那我在创建类的时候直接用调配符不就好了,支持各种类型自动转化 啊,我试过了不行!!!
//Syntax error on token "?", invalid TypeParameter
public class Student<?> {
...
}
报错啦,只能给具体的类或者T、E、a,b,c,e,d 等字母!!!!
就是不能使用通配符,通配符在
传入方法参数中使用!!!
在方法返回值类型中也不支持通配符!!!
public ? getId() {
return id;
}
Multiple markers at this line
- Syntax error on token “?”, delete this
token
好了,就这些,你看List、各种框架源码中涉及的也就这些吧。。。
拜拜
2017/6/23
一个类创建的时候包含泛型,我们再new 类的时候可以不带泛型,
当调用类中方法设计到泛型,会自动识别转换。
上面的student例子:
public static void main(String[] args) {
// TODO Auto-generated method stub
/*
Student is a raw type. References to generic type Student<T> should be parameterized
*/
Student student = new Student();
student.setId(123d);
getStuId(student);
。。。
}
打印
class java.lang.Double