泛型

本文详细介绍了泛型在Java中的应用,包括泛型定义在类、接口和方法上的不同方式及其使用场景,同时阐述了泛型通配符的概念及泛型限定的意义。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.当泛型定义在方法上:

定义泛型类:


这时肯定有个疑问,那形参的那个T不也是限制参数类型么?我的理解是,它是进行更详细的约束。

例如:(形参的T必须是Comparable的子类型)

public <T extends Comparable> T test(T t){
		return null;
}

public class GenericityTest1<Q> {
	private Q q;

	public Q getQ() {
		return q;
	}

	public void setQ(Q q) {
		this.q = q;
	}
	
	public void show(Q q){//这个方法使用的泛型是定义在类上的泛型,跟着类中的泛型走
		System.out.println(q);
	}
	
	public <W> void print(W w){//这个方法使用的泛型是定义此方法上的泛型
		System.out.println(w);
	}
	
	public static <W> void prin(W w){//由于这个方法是静态的,所以如果这个方法中若要使用泛型则必须是定义在方法中的,因为定义在类中的泛型必须有对象才有
		System.out.println(w);
	}
}


2.将泛型定义在接口上:

interface Inter<T>{
	public void show(T t);
}

当实现类实现这个接口的时候,有两种情况:

(1).实现这个接口的时候,已经知道实现类里泛型的类型:

class InterImpl implements Inter<String>{
	public void show(String t) {
		System.out.println(t);
	}
}

测试类:

public static void main(String[] args) {
		InterImpl i = new InterImpl();
		i.show("xxc");
}


(2).实现这个接口的时候,实现类还是不知道泛型需要定义什么类型:

class InterImpl1<T> implements Inter<T>{
	public void show(T t) {
		System.out.println(t);
	}
}

测试类:

public static void main(String[] args) {
		InterImpl1<Integer> i1 = new InterImpl1<Integer>();
		i1.show(1);
}



3.泛型的通配符:<?>匹配任何类型

<?>和<T>区别:

//只仅在出现类型不明确的情况下,并不对不明确类型进行操作才用通配符?
	private static void collectionIterator(Collection<?> list) {
		Iterator<?> i = list.iterator();
		while(i.hasNext()){
			System.out.println(i.next());
		}
	}
//T和?的区别是:当有些工具类要对返回值(返回值类型是传入的T类型)进行操作的时候,通配符?就不能满足。 因为不能写成 ? t = i.next();
private static <T> T collectionIterator1(Collection<T> list) {
	Iterator<T> i = list.iterator();
	/*while(i.hasNext()){
		T t = i.next();
		System.out.println(i.next());
	}*/
	T t = i.next();
	return t;
}



对泛型进行限定,既不是接收所有类型,也不是接收一种类型,而是接收一部分类型。因为泛型是不带有继承关系的。例如ArrayList<Person> list = new ArrayList<Student>();这个样是错误的,因为到底容器接收的是Person类型还是Student类型不确定。


? extends E:接收E类型或者E的子类型对象。设定上限。(一般存元素的时候使用设定上限,要么存的是这个父类型,要么存的是这个父类型的子类型。只有这样才能限定元素集合范围,如果说集合在存的时候限定的是下限,那么这个集合中元素类型是无穷的。例如TreeSet构造函数,参数是一个容器类型,这个容器需要设定上限,使得容器里的类型不是无穷的。)

TreeSet(Collection<? extendsE> c)
          构造一个包含指定 collection 元素的新 TreeSet,它按照其元素的自然顺序进行排序。

Person父类

public class Person {
	private String name;
	private int age;

	public Person() {
		super();
	}

	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

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

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}

}


Student子类继承Person

public class Student extends Person{

	public Student() {
		super();
	}
	public Student(String name, int age) {
		super(name,age);
	}
	
	@Override
	public String toString() {
		return "Student [getName()=" + getName() + ", getAge()=" + getAge()
				+ ", getClass()=" + getClass() + ", hashCode()=" + hashCode()
				+ ", toString()=" + super.toString() + "]";
	}
}

Worker子类继承Person

public class Worker extends Person{

	public Worker() {
		super();
	}
	
	public Worker(String name, int age) {
		super(name,age);
	}

	@Override
	public String toString() {
		return "Worker [getName()=" + getName() + ", getAge()=" + getAge()
				+ ", getClass()=" + getClass() + ", hashCode()=" + hashCode()
				+ ", toString()=" + super.toString() + "]";
	}
}

测试类

public class Test {
	public static void main(String[] args) {
		ArrayList<Student> list = new ArrayList<Student>();
		list.add(new Student("xxc1",1));
		list.add(new Student("xxc2",2));
		ArrayList<Worker> list1 = new ArrayList<Worker>();
		list1.add(new Worker("xxc1",1));
		list1.add(new Worker("xxc2",2));
		collectionIterator(list);
		collectionIterator(list1);
	}

	private static void collectionIterator(Collection<? extends Person> list) {//表示凡是Person的子类类型或者Person类型都可以被接收
		Iterator<? extends Person> i = list.iterator();
		while(i.hasNext()){
			Person p = i.next();
			System.out.println(p.getName()+":"+p.getAge());
		}
	}
}

? super E:接收E类型或者E的父类型对象。设定下限。(一般很少用,主要用在取出元素操作的时候,因为取元素的时候,接收类型要么是元素本身类型,要么是元素的父类型。例如TreeSet构造函数中的参数比较器:因为比较器需要取出两个元素进行比较,取的时候就必须用当前元素类型或者当前元素类型的父类型进行接收)
TreeSet(Comparator<? superE> comparator)
          构造一个新的空 TreeSet,它根据指定比较器进行排序。

public class Test {
	public static void main(String[] args) {
		ArrayList<Student> list = new ArrayList<Student>();
		list.add(new Student("xxc1",1));
		list.add(new Student("xxc2",2));
		ArrayList<Person> list1 = new ArrayList<Person>();
		list1.add(new Person("xxc1",1));
		list1.add(new Person("xxc2",2));
		collectionIterator(list);
		collectionIterator(list1);
	}

	private static void collectionIterator(Collection<? super Student> list) {//表示凡是Student的父类类型或者Student类型都可以被接收
		Iterator<? super Student> i = list.iterator();
		while(i.hasNext()){
			System.out.println(i.next());
		}
	}
}




                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值