简单的自定义泛型类

  • Post author:
  • Post category:其他


1.自定义泛型类可以先定义一个正常的实体类,里面有对应的属性和方法,例如:

package com;

import java.util.ArrayList;
import java.util.List;

public class order {
	private String orderName;
	private int orderId;
	
	public String getOrderName() {
		return orderName;
	}
	public void setOrderName(String orderName) {
		this.orderName = orderName;
	}
	public int getOrderId() {
		return orderId;
	}
	public void setOrderId(int orderId) {
		this.orderId = orderId;
	}
	@Override
	public String toString() {
		return "order [orderId=" + orderId + ", orderName=" + orderName + "]";
	}	
}

2.然后在属性中加入你想要加入的属性,并在类声明的地方加入有泛型的声明,例如:

package com;

import java.util.ArrayList;
import java.util.List;

//自定义泛型类
public class order<T> {
	private String orderName;
	private int orderId;
	private T t;
	List<T> list = new ArrayList<T>();
	public void add(){
		list.add(t);
	}
	public T getT(){
		return t;
	}
	public void setT(T t){
		this.t = t;
	}
	public String getOrderName() {
		return orderName;
	}
	public void setOrderName(String orderName) {
		this.orderName = orderName;
	}
	public int getOrderId() {
		return orderId;
	}
	public void setOrderId(int orderId) {
		this.orderId = orderId;
	}
	@Override
	public String toString() {
		return "order [orderId=" + orderId + ", orderName=" + orderName
				+ ", t=" + t + "]";
	}
	
	
}

3.关于泛型的使用,可以使用下面的方法:

package com;

import java.util.List;

//自定义泛型类的使用
public class testOrder {
	public static void main(String[] args) {
		order<Boolean> Order =  new order<Boolean>();
		Order.setT(true);
		System.out.println(Order.getT()+"===OTHER==="+Order.getOrderName());
		Order.add();
		Order.add();
		Order.add();
		List<Boolean> list = Order.list;
		System.out.println(list);
		System.out.println(Order.toString());
	}
}

4.控制台的输出为:

true===OTHER===null
[true, true, true]
order [orderId=0, orderName=null, t=true]

5.如果比较复杂的,例如多参的

package com;

public class Pair<T> {
	private T first;
	private T last;

	public T getFirst() {
		return first;
	}

	public void setFirst(T first) {
		this.first = first;
	}

	public T getLast() {
		return last;
	}

	public void setLast(T last) {
		this.last = last;
	}

	public Pair(T first, T last) {
		super();
		this.first = first;
		this.last = last;
	}
}

6.一些疑问

在这里插入图片描述

7.当然泛型还可以定义多种类型

例如:

package com;

public class Pair<T> {
	private T first;
	private T last;

	public T getFirst() {
		return first;
	}

	public void setFirst(T first) {
		this.first = first;
	}

	public T getLast() {
		return last;
	}

	public void setLast(T last) {
		this.last = last;
	}

	public Pair(T first, T last) {
		super();
		this.first = first;
		this.last = last;
	}
	
	/*静态方法创建泛型*/
	public static <K> Pair<K> create(K fir,K las)
	{
		return new Pair<K>(fir,las);
	}
	
}

8.还可以调用静态方法来进行创建下详见:


		Pair<Integer> p = Pair.create(1,2);
		System.out.println(p.getFirst()+"******"+p.getLast());

9.拓展见:


拓展


10.一个简单的泛型方法

package com;

import java.util.ArrayList;
import java.util.List;

public class fanxing {
	public static void main(String[] args) {
		List<DVD> list =new ArrayList<DVD>();
		DVD dvd = new DVD();
		test(DVD.class);
	}

	private static <T> void test(List<T> lt,T t,Class<T> thisclass) {
		if (thisclass == DVD.class) {
			lt.forEach(x ->{
				DVD dvd = (DVD)x;
			});
			DVD dvd1 = (DVD)t;
			System.out.println("you are right");
		}
	}
}

11.通配符。


类型通配符


我们知道Ingeter是Number的一个子类,同时Generic与Generic实际上是相同的一种基本类型。那么问题来了,在使用Generic作为形参的方法中,能否使用Generic的实例传入呢?在逻辑上类似于Generic和Generic是否可以看成具有父子关系的泛型类型呢?

为了弄清楚这个问题,我们使用Generic这个泛型类继续看下面的例子:

	public static void showKeyValue1(Generic<Number> obj) {
		System.out.println("key value is " + obj.getKey());
	}

	public static void main(String[] args) {
		Generic<Integer> gInteger = new Generic<Integer>(123);
		Generic<Number> gNumber = new Generic<Number>(456);

		showKeyValue1(gInteger);

		// showKeyValue这个方法编译器会为我们报错:Generic<java.lang.Integer>
		// cannot be applied to Generic<java.lang.Number>
		// showKeyValue(gInteger);
	}

通过提示信息我们可以看到Generic不能被看作为`Generic的子类。由此可以看出:同一种泛型可以对应多个版本(因为参数类型是不确定的),不同版本的泛型类实例是不兼容的。

回到上面的例子,如何解决上面的问题?总不能为了定义一个新的方法来处理Generic类型的类,这显然与java中的多台理念相违背。因此我们需要一个在逻辑上可以表示同时是Generic和Generic父类的引用类型。由此类型通配符应运而生。

我们可以将上面的方法改一下:

	public static void showKeyValue1(Generic<?> obj) {
		System.out.println("key value is " + obj.getKey());
	}

也可以这样表示:(限制的是输入的必须是number的子类)

	public static void showKeyValue1(Generic<? extends Number> obj) {
		System.out.println("key value is " + obj.getKey());
	}

类型通配符一般是使用?代替具体的类型实参,注意了,此处’?’是类型实参,而不是类型形参 。重要说三遍!此处’?’是类型实参,而不是类型形参 ! 此处’?’是类型实参,而不是类型形参 !再直白点的意思就是,此处的?和Number、String、Integer一样都是一种实际的类型,可以把?看成所有类型的父类。是一种真实的类型。

可以解决当具体类型不确定的时候,这个通配符就是 ? ;当操作类型时,不需要使用类型的具体功能时,只使用Object类中的功能。那么可以用 ? 通配符来表未知类型。


extends通配符


可以用来限制指定的泛型的范围,只能传入XX类以及XX类的子类,例如:

package com;

public class Pair<T extends Number> {
	private T first;
	private T last;
******************************************
}

	public void add(Pair<? extends Number> p){
		/***********/
	}

只能用P的get方法,不能用P的set方法,set(null)除外


super通配符


可以用来限制指定的泛型的范围,只能传入XX类以及XX类的父类,不能用来定义泛型,例如:

	public void add(Pair<? super Integer> p){
		/***********/
	}

只能用P的set方法,不能用P的get方法,get(object除外)

12.泛型的数组

不能直接用new来创建泛型数组,必须通过强制转换,如:

1.Pair < String>[] ps= null √

2.Pair < String>[] ps = new Pair< String>[2] ×

3.Pair < String>[] ps = (Pair< String>[]) new Pair [2] √

可以通过Array.newInstance(Class,int),创建T[]数组,组要强制转型



版权声明:本文为qq_23095607原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。