引用。原地址:http://www.java3z.com/cwbwebhome/article/article5/tiger2.jsp
清单 1
// 一个简单的范型类.
// 这里,T 是一个类型参数,当创建Gen类的对象时将被真实的类型取代.
public class Gen< T> {
T ob; // 声明一个T类型的对象
Gen(T o) {
ob = o;
}
public T getob() {
return ob;
}
// 输出T的类型
public void showType() {
System.out.println("Type of T is " +
ob.getClass().getName());
}
}
// 示范这个范型类的用法
public class GenDemo {
public static void main(String args[]) {
// 声明一个类型参数为Integers的Gen对象
Gen< Integer> iOb;
// 创建一个Gen< Integer> 对象并分配其引用到iOb. 注意使用了自动装箱.
iOb = new Gen< Integer>(88);
// 显示类型
iOb.showType();
// 获取在iOb对象内的值,注意不需要类型转换.
int v = iOb.getob();
System.out.println("value: " + v);
System.out.println();
// 创建一个类型参数为String的Gen对象
Gen< String> strOb = new Gen< String>("Generics Test");
strOb.showType();
String str = strOb.getob();
System.out.println("value: " + str);
}
}
清单2
// NonGen类没有使用范型, 与使用范型的Gen的等价
class NonGen {
Object ob; // ob 现在是一个Object类型
NonGen(Object o) {
ob = o;
}
// 返回类型为 Object.
Object getob() {
return ob;
}
// 显示ob的类型.
void showType() {
System.out.println("Type of ob is " +
ob.getClass().getName());
}
}
// 示范这个类用使用.
class NonGenDemo {
public static void main(String args[]) {
NonGen iOb;
// 自动装箱还会发生.
iOb = new NonGen(88);
iOb.showType();
// 输出iOb的值,必须进行类型转换
int v = (Integer) iOb.getob();
System.out.println("value: " + v);
System.out.println();
// 创建另一个对象,存字符串.
NonGen strOb = new NonGen("Non-Generics Test");
strOb.showType();
String str = (String) strOb.getob();
System.out.println("value: " + str);
// 下面这句编译能通过,因为没有语法错误
iOb = strOb;
v = (Integer) iOb.getob(); // 发生运行时错误!
}
}
清单 3
//带两个类型参数的范型
class TwoGen< T, V> {
T ob1;
V ob2;
TwoGen(T o1, V o2) {
ob1 = o1;
ob2 = o2;
}
// 显示T 和 V的类型.
void showTypes() {
System.out.println("Type of T is " +
ob1.getClass().getName());
System.out.println("Type of V is " +
ob2.getClass().getName());
}
T getob1() {
return ob1;
}
V getob2() {
return ob2;
}
}
// 示范.
class SimpGen {
public static void main(String args[]) {
TwoGen< Integer, String> tgObj =
new TwoGen< Integer, String>(88, "Generics");
tgObj.showTypes();
// 获取并显示值.
int v = tgObj.getob1();
System.out.println("value: " + v);
String str = tgObj.getob2();
System.out.println("value: " + str);
}
}
清单 4
// 尝试创建一个能计算数字平均值的泛型类
// 这个类包括一个错误!
class Stats< T> {
T[] nums; // nums 是一个T类型的数组
Stats(T[] o) {
nums = o;
}
// 所有的情况下都返回double.
double average() {
double sum = 0.0;
for(int i=0; i < nums.length; i++)
sum += nums[i].doubleValue(); // 错误!!!,编译器无法知道你只使用数字类型创建Stats对象.
return sum / nums.length;
}
}
清单 5
// 这次使用有界类型的范型,声明一个上界,所有类型变量必须从超类派生.
class Stats< T extends Number> {
T[] nums; // Number或它的子类型的数组
Stats(T[] o) {
nums = o;
}
double average() {
double sum = 0.0;
for(int i=0; i < nums.length; i++)
sum += nums[i].doubleValue();
return sum / nums.length;
}
}
// 示范
class BoundsDemo {
public static void main(String args[]) {
Integer inums[] = { 1, 2, 3, 4, 5 };
Stats< Integer> iob = new Stats< Integer>(inums);
double v = iob.average();
System.out.println("iob average is " + v);
Double dnums[] = { 1.1, 2.2, 3.3, 4.4, 5.5 };
Stats< Double> dob = new Stats< Double>(dnums);
double w = dob.average();
System.out.println("dob average is " + w);
// 这不能编译,因为String不是Number的子类
// String strs[] = { "1", "2", "3", "4", "5" };
// Stats< String> strob = new Stats< String>(strs);
// double x = strob.average();
// System.out.println("strob average is " + v);
}
}
清单 6
// 使用通配符
class Stats< T extends Number> {
T[] nums;
Stats(T[] o) {
nums = o;
}
double average() {
double sum = 0.0;
for(int i=0; i < nums.length; i++)
sum += nums[i].doubleValue();
return sum / nums.length;
}
// 确定两个包含数组的Stats对象是否有相同的平均值.
// 注意使用通配符
boolean sameAvg(Stats< ?> ob) {
if(average() == ob.average())
return true;
return false;
}
}
// 示范.
class WildcardDemo {
public static void main(String args[]) {
Integer inums[] = { 1, 2, 3, 4, 5 };
Stats< Integer> iob = new Stats< Integer>(inums);
double v = iob.average();
System.out.println("iob average is " + v);
Double dnums[] = { 1.1, 2.2, 3.3, 4.4, 5.5 };
Stats< Double> dob = new Stats< Double>(dnums);
double w = dob.average();
System.out.println("dob average is " + w);
Float fnums[] = { 1.0F, 2.0F, 3.0F, 4.0F, 5.0F };
Stats< Float> fob = new Stats< Float>(fnums);
double x = fob.average();
System.out.println("fob average is " + x);
// 看哪二个数组有相同的平均值.
System.out.print("Averages of iob and dob ");
if(iob.sameAvg(dob))
System.out.println("are the same.");
else
System.out.println("differ.");
System.out.print("Averages of iob and fob ");
if(iob.sameAvg(fob))
System.out.println("are the same.");
else
System.out.println("differ.");
}
}
运行结果:
C:\java>java WildcardDemo
iob average is 3.0
dob average is 3.3
fob average is 3.0
Averages of iob and dob differ.
Averages of iob and fob are the same.
listing 7
// 有界通配符.
// 二维空间.
class TwoD {
int x, y;
TwoD(int a, int b) {
x = a;
y = b;
}
}
// 三维空间.
class ThreeD extends TwoD {
int z;
ThreeD(int a, int b, int c) {
super(a, b);
z = c;
}
}
// 四维空间.
class FourD extends ThreeD {
int t;
FourD(int a, int b, int c, int d) {
super(a, b, c);
t = d;
}
}
class Coords< T extends TwoD> { //有界范型
T[] coords;
Coords(T[] o) { coords = o; }
}
// 示范.
class BoundedWildcard {
static void showXY(Coords< ?> c) {
System.out.println("X Y Coordinates:");
for(int i=0; i < c.coords.length; i++)
System.out.println(c.coords[i].x + " " +
c.coords[i].y);
System.out.println();
}
static void showXYZ(Coords< ? extends ThreeD> c) {
System.out.println("X Y Z Coordinates:");
for(int i=0; i < c.coords.length; i++)
System.out.println(c.coords[i].x + " " +
c.coords[i].y + " " +
c.coords[i].z);
System.out.println();
}
static void showAll(Coords< ? extends FourD> c) {
System.out.println("X Y Z T Coordinates:");
for(int i=0; i < c.coords.length; i++)
System.out.println(c.coords[i].x + " " +
c.coords[i].y + " " +
c.coords[i].z + " " +
c.coords[i].t);
System.out.println();
}
public static void main(String args[]) {
TwoD td[] = {
new TwoD(0, 0),
new TwoD(7, 9),
new TwoD(18, 4),
new TwoD(-1, -23)
};
Coords< TwoD> tdlocs = new Coords< TwoD>(td);
System.out.println("Contents of tdlocs.");
showXY(tdlocs); // OK, is a TwoD
// showXYZ(tdlocs); // Error, not a ThreeD
// showAll(tdlocs); // Erorr, not a FourD
// 创建一些四维点
FourD fd[] = {
new FourD(1, 2, 3, 4),
new FourD(6, 8, 14, 8),
new FourD(22, 9, 4, 9),
new FourD(3, -2, -23, 17)
};
Coords< FourD> fdlocs = new Coords< FourD>(fd);
System.out.println("Contents of fdlocs.");
//这些都不会产生错误.
showXY(fdlocs);
showXYZ(fdlocs);
showAll(fdlocs);
}
}
清单 8
// 示范简单的范型方法
class GenMethDemo {
// 静态的范型方法,测试一个对象是否在一个数组中.
static < T, V extends T> boolean isIn(T x, V[] y) {
for(int i=0; i < y.length; i++)
if(x.equals(y[i])) return true;
return false;
}
public static void main(String args[]) {
// 对Integers使用isIn()方法.
Integer nums[] = { 1, 2, 3, 4, 5 };
if(isIn(2, nums))
System.out.println("2 is in nums");
if(!isIn(7, nums))
System.out.println("7 is not in nums");
System.out.println();
// 对Strings使用isIn()
String strs[] = { "one", "two", "three",
"four", "five" };
if(isIn("two", strs))
System.out.println("two is in strs");
if(!isIn("seven", strs))
System.out.println("seven is not in strs");
// 不能编译,类型必须一致.
// if(isIn("two", nums))
// System.out.println("two is in strs");
}
}
清单 9
// 泛型构造器.
class GenCons {
private double val;
< T extends Number> GenCons(T arg) {
val = arg.doubleValue();
}
void showval() {
System.out.println("val: " + val);
}
}
class GenConsDemo {
public static void main(String args[]) {
GenCons test = new GenCons(100);
GenCons test2 = new GenCons(123.5F);
test.showval();
test2.showval();
}
}
运行结果:
C:\java>java GenConsDemo
val: 100.0
val: 123.5
清单 10
// 一个泛型接口的例子.
// 来用返回某个对象集的最小或最大值.
interface MinMax< T extends Comparable< T>> {
T min();
T max();
}
//MyClass实现接口MinMax
class MyClass< T extends Comparable< T>> implements MinMax< T> {
T[] vals;
MyClass(T[] o) { vals = o; }
// 返回最小值.
public T min() {
T v = vals[0];
for(int i=1; i < vals.length; i++)
if(vals[i].compareTo(v) < 0) v = vals[i];
return v;
}
// 返回最大值.
public T max() {
T v = vals[0];
for(int i=1; i < vals.length; i++)
if(vals[i].compareTo(v) > 0) v = vals[i];
return v;
}
}
class GenIFDemo {
public static void main(String args[]) {
Integer inums[] = {3, 6, 2, 8, 6 };
Character chs[] = {'b', 'r', 'p', 'w' };
MyClass< Integer> iob = new MyClass< Integer>(inums);
MyClass< Character> cob = new MyClass< Character>(chs);
System.out.println("Max value in inums: " + iob.max());
System.out.println("Min value in inums: " + iob.min());
System.out.println("Max value in chs: " + cob.max());
System.out.println("Min value in chs: " + cob.min());
}
}
清单 11
// 示范使用原始类型. 一个泛型类在使用时可以不带类型参数,同时带来的是失去了类型安全.
class Gen< T> {
T ob; // 声明一个T类型的对象
Gen(T o) {
ob = o;
}
T getob() {
return ob;
}
}
// 使用原始类型.
class RawDemo {
public static void main(String args[]) {
Gen< Integer> iOb = new Gen< Integer>(88);
Gen< String> strOb = new Gen< String>("Generics Test");
// 创建一个使用原始类型参数的Gen
Gen raw = new Gen(new Double(98.6));
// 类型转换是必须的
double d = (Double) raw.getob();
System.out.println("value: " + d);
//int i = (Integer) raw.getob(); // 运行时错误
strOb = raw; // 可以通过编译
// String str = strOb.getob(); // 运行时错误
raw = iOb; // 可能编译
// d = (Double) raw.getob(); // 运行时错误
}
}
清单 12
// 泛型类层次. 使用泛型超类
class Gen< T> {
T ob;
Gen(T o) {
ob = o;
}
// Return ob.
T getob() {
return ob;
}
}
// Gen的子类
class Gen2< T> extends Gen< T> {
Gen2(T o) {
super(o);
}
}
清单 13
// 子类能增加自己的类型参数.
class Gen< T> {
T ob;
Gen(T o) {
ob = o;
}
T getob() {
return ob;
}
}
class Gen2< T, V> extends Gen< T> {
V ob2;
Gen2(T o, V o2) {
super(o);
ob2 = o2;
}
V getob2() {
return ob2;
}
}
// 创建一个Gen2类型的对象.
class HierDemo {
public static void main(String args[]) {
Gen2< String, Integer> x = new Gen2< String, Integer>("Value is: ", 99);
System.out.print(x.getob());
System.out.println(x.getob2());
}
}
清单 14
// 泛型子类
class NonGen {
int num;
NonGen(int i) {
num = i;
}
int getnum() {
return num;
}
}
// 一个泛型子类
class Gen< T> extends NonGen {
T ob;
Gen(T o, int i) {
super(i);
ob = o;
}
T getob() {
return ob;
}
}
class HierDemo2 {
public static void main(String args[]) {
Gen< String> w = new Gen< String>("Hello", 47);
System.out.print(w.getob() + " ");
System.out.println(w.getnum());
}
}
清单 15
// 泛型层次中的运行时类型比较.
class Gen< T> {
T ob;
Gen(T o) {
ob = o;
}
T getob() {
return ob;
}
}
// Gen的子类.
class Gen2< T> extends Gen< T> {
Gen2(T o) {
super(o);
}
}
class HierDemo3 {
public static void main(String args[]) {
// Create a Gen object for Integers.
Gen< Integer> iOb = new Gen< Integer>(88);
// Create a Gen2 object for Integers.
Gen2< Integer> iOb2 = new Gen2< Integer>(99);
// Create a Gen2 object for Strings.
Gen2< String> strOb2 = new Gen2< String>("Generics Test");
// See if iOb2 is some form of Gen2.
if(iOb2 instanceof Gen2< ?>)
System.out.println("iOb2 is instance of Gen2");
// See if iOb2 is some form of Gen.
if(iOb2 instanceof Gen< ?>)
System.out.println("iOb2 is instance of Gen");
System.out.println();
// See if strOb2 is a Gen2.
if(strOb2 instanceof Gen2< ?>)
System.out.println("strOb is instance of Gen2");
// See if strOb2 is a Gen.
if(strOb2 instanceof Gen< ?>)
System.out.println("strOb is instance of Gen");
System.out.println();
// See if iOb is an instance of Gen2, which its not.
if(iOb instanceof Gen2< ?>)
System.out.println("iOb is instance of Gen2");
// See if iOb is an instance of Gen, which it is.
if(iOb instanceof Gen< ?>)
System.out.println("iOb is instance of Gen");
// The following can't be compiled because
// generic type info does not exist at runtime.
// if(iOb2 instanceof Gen2< Integer>)
// System.out.println("iOb2 is instance of Gen2< Integer>");
}
}
运行结果:
C:\java>java HierDemo3
iOb2 is instance of Gen2
iOb2 is instance of Gen
strOb is instance of Gen2
strOb is instance of Gen
iOb is instance of Gen
listing 16
// 重写泛型类中的方法
class Gen< T> {
T ob;
Gen(T o) {
ob = o;
}
T getob() {
System.out.print("Gen's getob(): " );
return ob;
}
}
// Gen的子类重写了getob().
class Gen2< T> extends Gen< T> {
Gen2(T o) {
super(o);
}
T getob() {
System.out.print("Gen2's getob(): ");
return ob;
}
}
// 演示重写泛型方法.
class OverrideDemo {
public static void main(String args[]) {
// Create a Gen object for Integers.
Gen< Integer> iOb = new Gen< Integer>(88);
// Create a Gen2 object for Integers.
Gen2< Integer> iOb2 = new Gen2< Integer>(99);
// Create a Gen2 object for Strings.
Gen2< String> strOb2 = new Gen2< String>("Generics Test");
System.out.println(iOb.getob());
System.out.println(iOb2.getob());
System.out.println(strOb2.getob());
}
}
运行结果:
C:\java>java OverrideDemo
Gen's getob(): 88
Gen2's getob(): 99
Gen2's getob(): Generics Test
清单 17
// 不使用泛型,迭代一个collection.
import java.util.*;
class OldStyle {
public static void main(String args[]) {
ArrayList list = new ArrayList();
list.add("one");
list.add("two");
list.add("three");
list.add("four");
Iterator itr = list.iterator();
while(itr.hasNext()) {
String str = (String) itr.next(); // 这里需要类型转换.
System.out.println(str + " is " + str.length() + " chars long.");
}
}
}
清单 18
// 新的泛型版本.
import java.util.*;
class NewStyle {
public static void main(String args[]) {
ArrayList< String> list = new ArrayList< String>();
list.add("one");
list.add("two");
list.add("three");
list.add("four");
// 注意Iterator 也是泛型.
Iterator< String> itr = list.iterator();
// Iterator< Integer> itr = list.iterator(); // 这样会产生编译错误!
while(itr.hasNext()) {
String str = itr.next(); // no cast needed
// Now, the following line is a compile-time,
// rather than runtime, error.
// Integer i = itr.next(); // this won't compile
System.out.println(str + " is " + str.length() + " chars long.");
}
}
}
清单 19(擦拭)
// 这个类编译后,T将被Object替换掉.
class Gen< T> {
T ob; // here, T will be replaced by Object
Gen(T o) {
ob = o;
}
// Return ob.
T getob() {
return ob;
}
}
// 编译后.这个类中的T 将被String替换.
class GenStr< T extends String> {
T str; // here, T will be replaced by String
GenStr(T o) {
str = o;
}
T getstr() { return str; }
}
清单 20
class GenTypeDemo {
public static void main(String args[]) {
Gen< Integer> iOb = new Gen< Integer>(99);
Gen< Float> fOb = new Gen< Float>(102.2F);
System.out.println(iOb.getClass().getName());
System.out.println(fOb.getClass().getName());
}
}
运行的输出:(在编译时所有类型都被擦拭了,运行时,只有原始类型存在.)
Gen
Gen