generics 是jdk 1.5 一个最重要的特性,主要用来处理collection。
以下代码在jdk 1.5 调试通过。
代码实例1: demo.java
代码实例2。sink.java
以下代码在jdk 1.5 调试通过。
代码实例1: demo.java
| package maoxiang.examples.jdk15.generics; import java.util.arraylist; import java.util.collection; import java.util.hashmap; import java.util.linkedlist; import java.util.list; import java.util.map; /** * @author 毛翔 * * 演示如何使用generics 特性。代码来自于 generics 教程: * http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf * * generics类似于c++中的模板。 * 区别: * 1. * 2. */ public class demo { public static void main(string[] args) {} /** * 最简单的用法 */ public void test1() { // 以前的用法 //list myintlist = new linkedlist(); // 1 //myintlist.add(new integer(0)); // 2 //integer x = (integer) myintlist.iterator().next(); // 3 需要强制转换 // 1.5 的用法 list<integer> myintlist = new linkedlist<integer>(); // 1’ myintlist.add(new integer(0)); //2’ integer x = myintlist.iterator().next(); // 3’ } /** * 匿名字符的用法 */ public void test2() { list<circle> list = new arraylist<circle>(); //通过匿名字符打印一个集合 wildcards(list); wildcards1(); /* * 如果 wildcards2 定义为wildcards2(list <shape> shapes) * 以下调用错误 */ wildcards2(list); } public void wildcards(collection< ? > c) { // 以前的用法 //iterator i = c.iterator(); //for (int k = 0; k < c.size(); k++) { // log(i.next()); //} //1.5 的用法 //collection<?> c 表示 for (object e : c) { log(e); } } public void wildcards1() { //collection<?> c = new arraylist<string>(); //c.add(new object()); // compile time error //以上为错误的用法,因为不能确定 c 的类型 ,不能使用add ,但get可以 。正确的用法如下: arraylist<string> c = new arraylist<string>(); c.add("test"); list< ? > list = c; log(c.get(0)); } public void wildcards2(list< ? extends shape> shapes) { //list<shape> shapes 定义只能接受list<shape> shapes,也不能接受 list<circle> for (shape s : shapes) { s.draw(); } //以下写法错误,因为为参数申明为 extends shpape,无法确定rectangle 为shape子类,属于不安全调用 //shapes.add(0, new rectangle()); map<string, driver> alldrivers = new hashmap<string, driver>(); census.addregistry(alldrivers); //以下写法允许,因为drivers明确定义, list<driver> drivers = new arraylist<driver>(); census.add(drivers); } /** * generic methods 的用法 * */ public void test3() { //适用于各种类型的函数 object[] oa = new object[100]; collection<object> co = new arraylist<object>(); fromarraytocollection(oa, co);// t inferred to be object string[] sa = new string[100]; collection<string> cs = new arraylist<string>(); fromarraytocollection(sa, cs);// t inferred to be string fromarraytocollection(sa, co);// t inferred to be object integer[] ia = new integer[100]; float[] fa = new float[100]; number[] na = new number[100]; collection<number> cn = new arraylist<number>(); fromarraytocollection(ia, cn);// t inferred to be number fromarraytocollection(fa, cn);// t inferred to be number fromarraytocollection(na, cn);// t inferred to be number fromarraytocollection(na, co);// t inferred to be object //test.fromarraytocollection(na, cs);// 错误用法 } public <t> void fromarraytocollection(t[] a, collection<t> c) { for (t o : a) { //如果参数定义为 collection< ? > c 以下写法错误 c.add(o); // compile time error } } /** * generics 嵌套用法 * @param shapes */ public void drawall(list< ? extends shape> shapes) { list<list< ? extends shape>> history = new arraylist<list< ? extends shape>>(); history.add(shapes); for (shape s : shapes) { s.draw(); } } /** * * */ public void test4() { list<string> l1 = new arraylist<string>(); list<integer> l2 = new arraylist<integer>(); system.out.print(l1.getclass() == l2.getclass()); //打印为 true, } /** * 错误用法 */ public void test5() { collection cs = new arraylist<string>(); //以下为错误用法 //if (cs instanceof collection<string>) { } // illegal //以下为警告用法 //collection<string> cstr = (collection<string>) cs; // unchecked // warning } public void test6() { //错误用法 //list<string>[] lsa = new list<string>[10]; // not really allowed list< ? >[] lsa = new list< ? >[10]; // ok, array of unbounded wildcard // type object o = lsa; object[] oa = (object[]) o; list<integer> li = new arraylist<integer>(); li.add(new integer(3)); oa[1] = li; // correct //string s = lsa[1].get(0); // run-time error - classcastexception //string s = lsa[1].get(0); // run time error, but we were warned string s = (string) lsa[1].get(0); // run time error, but cast is // explicit } public void test7() { sink<object> s = null; sink<string> s1 = null; collection<string> cs = null; string str = writeall(cs, s1); //string str = writeall(cs, s); // 无效调用 object obj = writeall1(cs, s); // 正确的调用 str = writeall2(cs, s1); // 正确的调用 } public <t> t writeall(collection<t> coll, sink<t> snk) { t last = null; for (t t : coll) { last = t; snk.flush(last); } return last; } public <t> t writeall1(collection< ? extends t> coll, sink<t> snk) { t last = null; for (t t : coll) { last = t; snk.flush(last); } return last; } public <t> t writeall2(collection<t> coll, sink< ? super t> snk) { t last = null; for (t t : coll) { last = t; snk.flush(last); } return last; } // 打印 private void log(object ob) { system.out.print(ob); } } //辅助定义 abstract class shape { public abstract void draw(); } class circle extends shape { private int x, y, radius; public void draw() { } } class rectangle extends shape { private int x, y, width, height; public void draw() { } } class person {} class driver extends person {} class census { public static void addregistry(map<string, ? extends person> registry) { } public static void add(list< ? extends person> persons) { } } class collections { public static <t, s extends t> void copy(list<t> dest, list<s> src) { } } |
代码实例2。sink.java
| package maoxiang.examples.jdk15.generics; /** * * @author 毛翔 * * 定义一个接口模板,简化了接口的定义 * */ interface sink<e> { public void flush(e t); } /* * 如果是以前的定义,则要定义要各种类型的接口,显然更麻烦 * interface sink { * * public void flush(string str); * public void flush(object obj); * public void flush(integer test); * ...... * } */ |
闽公网安备 35060202000074号