JAVA泛型应用

泛型接口

a. 接口上自定义的泛型参数的具体数据类型,是在 其实现类 实现该接口 的时候指定的。

b. 若在实现该泛型接口的时候,未指定具体的数据类型,则默认为OBJECT

c. 有些时候我们在定义一个类去实现泛型接口时,我们并不确定这个类将要实现哪种类型的类,这时我们就不能确定接口中的泛型,那么接口中的泛型尚未确认,这时就要求这个类也必须定义泛型,而且泛型名称要一致,在实例化这个类的对象时,需要指定该泛型的类型,若不指定,默认为OBJECT

 

 

泛型类

当类中要操作的数据类型不确定的时候,可以定义泛型类(集合体系中的类)。格式如下:

 

泛型类与泛型方法

泛型类在声明对象的时候,就已经定义好了能操作的数据类型,因此,在调用该类的方法时,不可避免的限定了方法的参数类型。这时,定义泛型方法就比较方便。泛型类中也可以定义泛型方法。

静态方法不可以访问类上定义的泛型,如果静态方法操作的数据类型不确定,可以将该方法定义为泛型方法。

 

泛型方法

形式: public <T> void show(T t){.....}

public static <W> int sum(W w){.....}

必须放在修饰符之后,返回值之前。

 

package genericType;

import testkit.Lf;
/**
 * @author: LiFeng
 * 	1. 定义泛型方法时,必须在返回值前边加一个<T>,来声明这是一个泛型方法,doSome3()就不是一个泛型方法 
 * 	2. 是否是泛型方法与该类是否是泛型类无关,即该类即使不存在泛型E,doSome()和doSome1()依然是成立的泛型方法 
 *      3. 既然是泛型方法,就代表着我们不知道具体的类型是什么,因此无法对参数类型指定前对其做具体操作
 *  优势:泛型类要在实例化的时候就指明类型,如果想换一种类型,不得不重新new一次,可能不够灵活; 
 *     		而泛型方法可以在调用的时候指明类型,更加灵活。
 *  劣势:泛型方法的劣势也很明显,太过泛化,导致无法限制实参范围,无法在该方法被调用之前获知实参的具体属性,
 *     		所以也就无法在方法体内部对参数t 做一些具体操作,只能当作Object处理。
 */

public class GTest3<E> {

	public <T> T doSome(Class<T> t) throws InstantiationException, IllegalAccessException {
		T instance = t.newInstance();
		return instance;
	}

	public <T> T doSome1(T t) {
		return t;
	}

	public <F> E doSome2(Class<F> f, E e) {
		return e;
	}

	public void doSome3(E e) {

	}

	public static void main(String[] args)
			throws  ClassNotFoundException, InstantiationException, IllegalAccessException {
		GTest3<String> gt3 = new GTest3<>();
		
		Lf return1 = gt3.doSome(Lf.class);
		Object return2 = gt3.doSome(Class.forName("testkit.Lf"));
		Lf return3 = gt3.doSome1(new Lf());
		
		System.out.println(return1);
		System.out.println(return2);
		System.out.println(return3);
	}
}

泛型方法补充:

泛型方法并不一定需要泛型参数,或者说不一定需要将泛型声明T作为参数传入,如下例方法,在调用deserialize反序列化方法时,其返回值我们可以定义为任意类型,这不会导致任何编译报错,一个简单的测试demo如下,这就体现了泛型的好处。但是在运行时需要我们更加小心,避免类型转换异常。

对于静态的泛型方法,再举一些例子

public final class Optional<T> {
    /**
     * Common instance for {@code empty()}.
     */
    private static final Optional<?> EMPTY = new Optional<>();  

    public static<T> Optional<T> empty() {
        @SuppressWarnings("unchecked")
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
     }
}
package future;

/**
 * @author LiFeng
 * @create 2019-11-03 上午 11:40
 * @describe
 */
public class Test1122 {


	public static <S> S empty(Object obj) {
		return (S) obj;
	}

	public static void main(String[] args) {

		// 不指定泛型,默认返回值为Object
		Object empty3 = empty("sss");

		// 通过返回值指定泛型,编译器能够识别通过,但是真正执行过程中,如果不注意,是会出现强转异常的
//		int i = empty("sss");  编译时通过。运行时无法通过会报错
		int i = empty(2);

		
		// 如果仅仅是调用而不使用其返回值的话,运行时也并不会报错。
		Test1122.<Integer>empty("aaa");
		// 试图使用方法返回值时,会将其转换为String类型,这里会出强转异常
//		Test1122.<String>empty(1).length();

		// 下面这两种效果一样,尽管后者在写法上比较特殊,但都是为了使编译器能够识别,让其得知我们所需要的返回值类型
		String string = empty("aaa");
		Test1122.<String>empty("aaa").length(); // 即使是本类中,这种写法强制一定要加上类名进行调用,Test1122不可省略

	}

}

 

 public <T> T deserialize(byte[] bytes) {
        if (bytes == null) {
            return null;
        }
        ByteArrayInputStream bais = null;
        ObjectInputStream ois = null;
        try {
            bais = new ByteArrayInputStream(bytes);
            ois = new ObjectInputStream(bais);
            return (T) ois.readObject();
        } catch (ClassNotFoundException e) {
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            if (ois != null) {
                try {
                    ois.close();
                } catch (IOException e) {
                }
            }
            if (bais != null) {
                try {
                    bais.close();
                } catch (IOException e) {
                }
            }
        }
    }

对于泛型限定,列举一个略微绕的例子:

interface ISortVO<S extends ISortVO<S>> extends Comparable<S>{
	
}

class A implements ISortVO<B>{

	@Override
	public int compareTo(B o) {
		return 0;
	}
	
}

class B implements ISortVO<B>{

	@Override
	public int compareTo(B o) {
		return 0;
	}
	
}

class C implements ISortVO<B>{

	@Override
	public int compareTo(B o) {
		return 0;
	}
	
}

在这个例子中,其实看明白了也挺简单,ISortVo 的泛型必须是符合类B这种格式的实现类,A和C是不满足泛型要求的。


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值