作者:管斌(苏州星动) blog:(http://blog.matrix.org.cn/page/guanbing)
在已发布的java1.4中在核心代码库中增加了许多新的api(如loging,正则表达式,nio)等,在最新发布的jdk1.5和即将发布的jdk1.6中也新增了许多api,其中比较有重大意义的就是generics(范型)。
一.什么是generics?
generics可以称之为参数类型(parameterized types),由编译器来验证从客户端将一种类型传送给某一对象的机制。如java.util.arraylist,
编译器可以用generics来保证类型安全。
在我们深入了解generics之前,我们先来看一看当前的java 集合框架(collection)。在j2se1.4中所有集合的root interface是collection
collections example without genericity: example 1
1 protected void collectionsexample() {
2 arraylist list = new arraylist();
3 list.add(new string("test string"));
4 list.add(new integer(9)); // purposely placed here to create a runtime classcastexception
5 inspectcollection(list);
6 }
7
8
9 protected void inspectcollection(collection acollection) {
10 iterator i = acollection.iterator();
11 while (i.hasnext()) {
12 string element = (string) i.next();
13 }
14 }1 protected void collectionsexample() {
2 arraylist<string> list = new arraylist<string>();
3 list.add(new string("test string"));
4 // list.add(new integer(9)); this no longer compiles
5 inspectcollection(list);
6 }
7
8
9 protected void inspectcollection(collection<string> acollection) {
10 iterator<string> i = acollection.iterator();
11 while(i.hasnext()) {
12 string element = i.next();
13 }
14 }1 public class arraylist<e> extends abstractlist<e> {
2 // details omitted...
3 public void add(e element) {
4 // details omitted
5 }
6 public iterator<e> iterator() {
7 // details omitted
8 }
9 }1 public <t extends comparable> t max(t t1, t t2) {
2 if (t1.compareto(t2) > 0)
3 return t1;
4 else return t2;
5 }1 integer iresult = max(new integer(100), new integer(200));
2 string sresult = max("aa", "bb");
3 number nresult = max(new integer(100), "aaa"); // does not compile
list<string> stringlist = new arraylist<string>(); //1
list<object> objectlist = stringlist ;//2
objectlist .add(new object()); // 3
string s = stringlist .get(0);//4
void printcollection(collection<object> c)
{ for (object e : c) {
system.out.println(e);
}}
void printcollection(collection<?> c)
{ for (object e : c) {
system.out.println(e);
}}
class nongen {
object ob; // ob is now of type object
// pass the constructor a reference to
// an object of type object
nongen(object o) {
ob = o;
}
// return type object.
object getob() {
return ob;
}
// show type of ob.
void showtype() {
system.out.println("type of ob is " +
ob.getclass().getname());
}
}
// demonstrate the non-generic class.
public class nongendemo {
public static void main(string args[]) {
nongen iob;
// create nongen object and store
// an integer in it. autoboxing still occurs.
iob = new nongen(88);
// show the type of data used by iob.
iob.showtype();
// get the value of iob.
// this time, a cast is necessary.
int v = (integer) iob.getob();
system.out.println("value: " + v);
system.out.println();
// create another nongen object and
// store a string in it.
nongen strob = new nongen("non-generics test");
// show the type of data used by strob.
strob.showtype();
// get the value of strob.
// again, notice that a cast is necessary.
string str = (string) strob.getob();
system.out.println("value: " + str);
// this compiles, but is conceptually wrong!
iob = strob;
v = (integer) iob.getob(); // runtime error!
}
} class example1<t>{
private t t;
example1(t o){
this.t=o;
}
t getob(){
return t;
}
void showobject(){
system.out.println("对象的类型是:"+t.getclass().getname());
}
}
public class genericsexample1 {
/**
* @param args
*/
public static void main(string[] args) {
// todo auto-generated method stub
example1<integer> examplei=new example1<integer>(100);
examplei.showobject();
system.out.println("对象是:"+examplei.getob());
example1<string> examples=new example1<string>("bill");
examples.showobject();
system.out.println("对象是:"+examples.getob());
}
}class twogen<t, v> {
t ob1;
v ob2;
// pass the constructor a reference to
// an object of type t.
twogen(t o1, v o2) {
ob1 = o1;
ob2 = o2;
}
// show types of t and 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;
}
}
public class genericsexamplebytwoparam {
/**
* @param args
*/
public static void main(string[] args) {
// todo auto-generated method stub
twogen<integer, string> tgobj =
new twogen<integer, string>(88, "generics");
// show the types.
tgobj.showtypes();
// obtain and show values.
int v = tgobj.getob1();
system.out.println("value: " + v);
string str = tgobj.getob2();
system.out.println("value: " + str);
}
}class stats<t extends number> {
t[] nums; // array of number or subclass
// pass the constructor a reference to
// an array of type number or subclass.
stats(t[] o) {
nums = o;
}
// return type double in all cases.
double average() {
double sum = 0.0;
for(int i=0; i < nums.length; i++)
sum += nums[i].doublevalue();
return sum / nums.length;
}
}
public class genericsexamplebyhierarchy {
/**
* @param args
*/
public static void main(string[] args) {
// todo auto-generated method stub
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);
// this won't compile because string is not a
// subclass of 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);
}
} class statswildcard<t extends number> {
t[] nums; // array of number or subclass
// pass the constructor a reference to
// an array of type number or subclass.
statswildcard(t[] o) {
nums = o;
}
// return type double in all cases.
double average() {
double sum = 0.0;
for (int i = 0; i < nums.length; i++)
sum += nums[i].doublevalue();
return sum / nums.length;
}
// determine if two averages are the same.
// notice the use of the wildcard.
boolean sameavg(statswildcard<?> ob) {
if (average() == ob.average())
return true;
return false;
}
}
public class genericsexamplebywildcard {
/**
* @param args
*/
public static void main(string[] args) {
// todo auto-generated method stub
integer inums[] = { 1, 2, 3, 4, 5 };
statswildcard<integer> iob = new statswildcard<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 };
statswildcard<double> dob = new statswildcard<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 };
statswildcard<float> fob = new statswildcard<float>(fnums);
double x = fob.average();
system.out.println("fob average is " + x);
// see which arrays have same average.
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.");
}
}class twod {
int x, y;
twod(int a, int b) {
x = a;
y = b;
}
}
// three-dimensional coordinates.
class threed extends twod {
int z;
threed(int a, int b, int c) {
super(a, b);
z = c;
}
}
// four-dimensional coordinates.
class fourd extends threed {
int t;
fourd(int a, int b, int c, int d) {
super(a, b, c);
t = d;
}
}
// this class holds an array of coordinate objects.
class coords<t extends twod> {
t[] coords;
coords(t[] o) { coords = o; }
}
// demonstrate a bounded wildcard.
public 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
// now, create some fourd objects.
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.");
// these are all ok.
showxy(fdlocs);
showxyz(fdlocs);
showall(fdlocs);
}
} public class arraylistgenericdemo {
public static void main(string[] args) {
arraylist<string> data = new arraylist<string>();
data.add("hello");
data.add("goodbye");
// data.add(new date()); this won't compile!
iterator<string> it = data.iterator();
while (it.hasnext()) {
string s = it.next();
system.out.println(s);
}
}
} public class hashdemogeneric {
public static void main(string[] args) {
hashmap<integer,string> map = new hashmap<integer,string>();
map.put(1, "ian");
map.put(42, "scott");
map.put(123, "somebody else");
string name = map.get(42);
system.out.println(name);
}
} interface minmax<t extends comparable<t>> {
t min();
t max();
}
// now, implement minmax
class myclass<t extends comparable<t>> implements minmax<t> {
t[] vals;
myclass(t[] o) { vals = o; }
// return the minimum value in vals.
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;
}
// return the maximum value in vals.
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;
}
}
public 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());
}
} interface executor<e extends exception> {
void execute() throws e;
}
public class genericexceptiontest {
public static void main(string args[]) {
try {
executor<ioexception> e =
new executor<ioexception>() {
public void execute() throws ioexception
{
// code here that may throw an
// ioexception or a subtype of
// ioexception
}
};
e.execute();
} catch(ioexception ioe) {
system.out.println("ioexception: " + ioe);
ioe.printstacktrace();
}
}
}
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器