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[]数组,组要强制转型