1 泛型在类上的引用
【案例1】创建类MyData,使用<>就有了泛型
public class MyData<T> {
private T data;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
【案例2】使用泛型
public class TestOne {
public static void main(String[] args) {
// 在创建支持泛型的类的对象时给出泛型的具体类型
// 支持泛型的类在不给出泛型具体类型时,泛型被当做Object
// 引用类型的泛型必须和对象类型的泛型一致,泛型不支持多态
// 方式一 — 不推荐
// MyData<String> myData = new MyData<String>();
// 方式二 — 不推荐
// MyData<String> myData = new MyData();
// 方式三 — 推荐使用
MyData<String> myData = new MyData<>();
myData.setData("Tom");
System.out.println(myData.getData());
}
}
【案例3】
// 1. 方式一
// 在子类继承父类时给出父类的泛型具体类型(这里是String)
public class SubMyData extends MyData<String> {
@Override
public String getData() {
return super.getData();
}
@Override
public void setData(String data) {
super.setData(data);
}
// 方式二
// 子类继承父类的泛型,子类也做成泛型的类
public class SubMyData<T> extends MyData<T> {
@Override
public T getData() {
return super.getData();
}
@Override
public void setData(T data) {
super.setData(data);
}
}
2 泛型在接口上的使用
【案例1】
public interface MyInterOne<T> {
//1.静态成员不支持泛型
// public static final T data; ×
//2.泛型在方法上的使用
//2.1 返回值是泛型
public T methodOne();
//2.2 参数是泛型
public void methodTwo(T t);
//2.3 返回值、参数都是泛型
public T methodThree(T t);
}
【案例2】推荐方式三
// 1.接口的泛型需要在实现类实现接口时确定泛型的具体类型
// 如果实现类没有确定泛型的具体的类型则视作Object
public class MyInterOneImpl implements MyInterOne {
@Override
public Object methodOne() {
return null;
}
@Override
public void methodTwo(Object o) {
}
@Override
public Object methodThree(Object o) {
return null;
}
// 2. 实现类实现泛型时给出泛型的具体类型
public class MyInterOneImpl implements MyInterOne<String> {
@Override
public String methodOne() {
return null;
}
@Override
public void methodTwo(String s) {
}
@Override
public String methodThree(String s) {
return null;
}
// 3.实现类实现接口时继承接口的泛型
public class MyInterOneImpl<T> implements MyInterOne<T> {
@Override
public T methodOne() {
return null;
}
@Override
public void methodTwo(T t) {
}
@Override
public T methodThree(T t) {
return null;
}
}
【案例3】
public class TestTwo {
public static void main(String[] args) {
// 创建接口实现类对象时给出泛型的具体类型
MyInterOne<String> myInterOne = new MyInterOneImpl<>();
}
}
3 类型通配符
public class TestThree {
public static void main(String[] args) {
Collection<String> col1 = new ArrayList<>();
col1.add("Tom");
col1.add("Jerry");
col1.add("Mary");
Collection<Integer> col2 = new ArrayList<>();
col2.add(10);
col2.add(20);
col2.add(30);
methodOne(col1);
methodTwo(col1);
methodOne(col2);
// methodTwo(col2);
methodThree(col1);
methodThree(col2);
Collection<Animal> col3 = new ArrayList<>();
Collection<Dog> col4 = new ArrayList<>();
Collection<Cat> col5 = new ArrayList<>();
methodThree(col3);
methodFour(col3);
methodFour(col4);
methodFour(col5);
methodFive(col3);
// methodFive(col4);
methodFive(col5);
}
public static void methodOne(Collection col){
for (Object o : col) {
System.out.println(o);
}
}
public static void methodTwo(Collection<String> col){
for (String s : col) {
System.out.println(s);
}
}
// ?是泛型形参的通配类型,这种类型可以匹配任何支持泛型的实参
public static void methodThree(Collection<?> col){
for (Object o : col) {
System.out.println(o);
}
}
// 这种方式指定了泛型通配的父类,可以包含父类及父类的子类类型,相当于指定了泛型的上限
public static void methodFour(Collection<? extends Animal> col){
for (Animal animal : col) {
System.out.println(animal);
}
}
// 这种方式指定了通配类型必须是Cat或者Cat的父类对象,相当于指定了泛型的下限
public static void methodFive(Collection<? super Cat> col){
for (Object o : col) {
System.out.println(o);
}
}
}
class Animal{}
class Dog extends Animal{}
class Cat extends Animal{}
4 泛型的集合
【案例】
public class TestFour {
public static void main(String[] args) {
// 泛型的集合
List<String> list = new ArrayList<>();
list.add("Tom");
String s = list.get(0);
// 迭代器可以指定泛型,但是迭代器的泛型必须和集合的泛型一致
Iterator<String> iter = list.iterator();
Map<String, Student> map = new HashMap<>();
// Map可以单独指定键和值的泛型,键集泛型必须和键泛型一致,值集泛型必须和值泛型一致
Set<String> keys = map.keySet();
Collection<Student> values = map.values();
}
}
标签:String,void,public,Override,泛型,class From: https://www.cnblogs.com/apple677/p/16060966.html