泛型(一)

泛型是JDK5时的技术,主要作用于编译时期,是编译时期的安全技术。

一、元组

1、引入:仅一次方法调用就能返回多个对象,编码中应该会使用到该功能。但是对于一个方法的return来说,一次只能返回一个对象。因此,解决办法就是创建一个对象,让其持有想要返回的多个对象。每次需要该种场景的情况时,我们就创建一个类来完成工作。

2、元组:将一组对象直接打包存储于一个单一的对象中。可以理解为元组为一个容器对象,该容器对象只允许读取其中的元素,不允许向其中存放新的元素。因此,该对象的成员声明时用final修饰。

3、示例如下:

package net.oschina.tkj.chapter15.tuple;

/**
 * 元组类
 * 
 * @author Freedom
 * 
 * @param <A>
 * @param <B>
 */
public class TwoTuple<A, B> {

	private final A a;
	public final B b;

	public TwoTuple(A a, B b) {
		this.a = a;
		this.b = b;
	}

	public A getA() {
		return a;
	}

	public B getB() {
		return b;
	}

	@Override
	public String toString() {
		return "TwoTuple [a=" + a + ", b=" + b + "]";
	}
	
	public static void main(String[] args) {

		Red red = new Red();
		red.setAge(11);
		red.setName("红色方");

		VmInfo vm = new VmInfo();
		vm.setVmId(1);
		vm.setVmName("POPDAS");
		vm.setVmNum(2);

		// 二元元组
		TwoTuple<Red, VmInfo> two = new TwoTuple<Red, VmInfo>(red, vm);
		System.out.println("元组对象:"+two);
		
		// 获取元组中的成员
		VmInfo tupleRed = two.getB();
		Red redTuple = two.getA();

		System.out.println("tupleRed:" + tupleRed);
		System.out.println("redTuple:" + redTuple);

	}

}

二、泛型类模拟一个简单堆栈

1、代码示例

package net.oschina.tkj.chapter15.stack;

/**
 * 泛型类,简单的堆栈
 * 
 * @author Freedom
 * 
 */
public class SimpleStack<T> {

	/*
	 * 内部类用于提供数据
	 */
	private static class Node<K> {

		K item;
		Node<K> next;

		// 创建外部类对象时,同时创建一个内部类型对象,该对象为末端哨兵
		Node() {
			this.item = null;
			this.next = null;
		}

		Node(K item, Node<K> next) {
			this.item = item;
			this.next = next;
		}

		boolean end() {
			return item == null && next == null;
		}

	}

	// 创建外部类对象时,初始化一个内部类对象,充当末端哨兵
	private Node<T> bottom = new Node<T>();

	// 添加元素
	public void push(T item) {
		bottom = new Node<T>(item, bottom);
	}

	// 取出元素
	public T pop() {
		T res = bottom.item;
		if (!bottom.end()) {
			bottom = bottom.next;
		}
		return res;
	}

	public static void main(String[] args) {

		SimpleStack<String> simple = new SimpleStack<String>();
		String str = "this is a luck dog";
		for (String s : str.split(" ")) {
			simple.push(s);
		}

		String s;
		while ((s = simple.pop()) != null) {
			System.out.print(s+" ");
		}
	}

}

 

 

示例中使用了末端哨兵的功能,来判断堆栈何时为空。

三、泛型方法

1、类中可以包含参数化的方法,而该方法所在的类可以是泛型类,也可以不是泛型类。简言之,泛型方法与泛型类没有必然关系。

2、泛型方法使用原则:

①使用泛型方法可以取代整个类的泛型化,则优先使用泛型方法;

②对static方法而言,无法访问泛型类的类型参数(报错信息:Cannot make a static reference to the non-static type T);如果static方法需要使用泛型能力,必须要在自己的方法上声明泛型(原因:因为类上声明的参数化类型,需要创建的对象的时具体制定,对于static方法而言,可以不用创建对象直接调用,此时不能知道参数化的具体类型,因此编译不通过;通过方法声明时,在调用方法时可以确定具体的泛型的类型)

错误示例:

package net.oschina.tkj.chapter15.method;

public class GenerateMethods<T> {

	/*
	 * 该方法会报错:Cannot make a static reference to the non-static type T
	 * static方法无法访问泛型类的类型参数
	 */
	public static void f(T t) {
	}

	/*
	 * 该方法正确,是static方法具备泛型能力,必须在自己的方法上声明泛型
	 */
	public static <K> void f1(K k) {
	}
}

泛型方法示例:

package net.oschina.tkj.chapter15.method;

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

import net.oschina.tkj.chapter15.tuple.TwoTuple;
import net.oschina.tkj.chapter15.tupleclass.Red;
import net.oschina.tkj.chapter15.tupleclass.VnfInfo;

public class GenerateMethods<T> {

	/*
	 * 非static方法可以直接使用,泛型类声明的泛型类型
	 */
	public void g(T t) {
	}

	/*
	 * 如下static方法需在自己方法上声明泛型类型
	 */
	public static <T> void f(T t) {
		System.out.println(t.getClass().getSimpleName());
	}

	public static <K, V> TwoTuple<K, V> f1(K k, V v) {
		return new TwoTuple<K, V>(k, v);
	}

	public static <T> List<T> f2(T... args) {

		List<T> list = new ArrayList<T>();
		for (T t : args) {
			list.add(t);
		}
		return list;
	}

	public static void main(String[] args) {

		// 泛型方法
		f(new Red());

		TwoTuple<Red, VnfInfo> method = f1(new Red(), new VnfInfo());
		System.out.println("method:" + method);

		f2("a", "b", "c");
		f2(new String[] { "c", "d", "e" });
		f2(new ArrayList<String>());
		List<Object> list = f2(new Red(), new VnfInfo());
		for (Object o : list) {
			System.out.println(o);
		}
	}

}

如上:未完待续......

猜你喜欢

转载自1498116590.iteye.com/blog/2405576
今日推荐