免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 7490 | 回复: 21
打印 上一主题 下一主题

老虎来了,你准备好了吗?(增加for-each) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2004-03-03 19:57 |只看该作者 |倒序浏览
老虎来了,你准备好了吗?

也不知什么时候,Sun推出了Tiger的Beta版(J2SE 1.5.0 Beta 1).
早在Sun公布Tiger草案时,就对它是又爱又恨,一下子加了那么多得编程特性( http://www.chinaunix.net/forum/viewtopic.php?t=104044 ),真不知道会不会适应不过来.不过,所谓"兵来将挡",不入虎穴,焉得虎子,请大家与我一起进入"Tiger"的世界.

1.下载及安装
第一步当然就是把老虎请到我们的家中来咯.
先到http://java.sun.com, 或者 http://java.sun.com/j2se/1.5.0/index.jsp ,就可以发现在右侧Popular Downloads里的赫然就是我们要找的"Tiger",点击进入 http://java.sun.com/j2se/1.5.0/download.jsp ,点击SDK 下面的download,同意协议,再选择相应的平台,windowns 48M,Sparc64只需要9M,点击下载,或者可以直接右键使用Flashget/Netant下载.
呵呵,记得回到 http://java.sun.com/j2se/1.5.0/download.jsp 同时把Docment也给download下来.

下载完毕就可以开始安装了,当然,安装前先看看Installation Notes,Window下的没什么特别,solaris64好像还需要打patch.
我用的是windows,运行下载的文件(用flashget下载的好像需要改扩展名为.exe),跟着wizard往下走,默认安装路径是 C:\Program Files\Java\j2sdk1.5.0\,如果你和我一样讨厌空格,可以把它放在C:\j2sdk1.5.0,中间的安装步骤就不用说了,十几二十分钟,安装就完成了.把下载来的docment也顺便给解开,放在C:\j2sdk1.5.0\doc下.

2.环境配置
安装完毕之后,就需要配置一下环境,改动一下两个环境变量
JAVA_HOME=c:\j2sdk1.5.0
PATH=c:\j2sdk1.5.0\bin;......(原来的PATH)

3.Hello World
好了,现在Tiger已经在电脑里安了身了.下面,我们就开始我们的骑虎之旅吧.

正如 http://www.chinaunix.net/forum/viewtopic.php?t=104044 里提到的,java语言规范(JSR)201有不少变化.其中,在集合的Frame里有几个重要的变化,让我们以这几个变化中的 generic 开始展开骑虎之旅.


generic指的就是对特定的集合,只能容纳特定的类的对象,而在取出来时不需做Cast.他的语法类似

  1. Vector<String>; v = new Vector<String>;();
  2. c.add("test");
  3. String s = c.get("test");
复制代码

我们就以上面的代码为例

  1. //GenricTest.java
  2. import java.util.*;
  3. public class GenricTest{
  4. public static void main(String args[]){
  5. Vector<String>; v = new Vector<String>;();
  6. v.add("Hello World");
  7. String s = v.get(0);
  8. System.out.println(s);
  9. }
  10. }
复制代码

保存,javac之......
却出现了这个

  1. GenricTest.java:4: '(' or '[' expected
  2. Vector<String>; v = new Vector<String>;();
  3.                              ^
  4. 1 error
复制代码


怎么回事?呵呵明天回来告诉你.

论坛徽章:
0
2 [报告]
发表于 2004-03-03 20:15 |只看该作者

老虎来了,你准备好了吗?(增加for-each)

关注

论坛徽章:
0
3 [报告]
发表于 2004-03-04 11:59 |只看该作者

老虎来了,你准备好了吗?(增加for-each)

其实我是来灌水的

论坛徽章:
0
4 [报告]
发表于 2004-03-04 13:17 |只看该作者

老虎来了,你准备好了吗?(增加for-each)

just few days I got the news about this big change ,so please give more information about this and quick.
thank you
and I think every one will appreciate it.

论坛徽章:
0
5 [报告]
发表于 2004-03-04 13:57 |只看该作者

老虎来了,你准备好了吗?(增加for-each)

attention---------high attention

论坛徽章:
0
6 [报告]
发表于 2004-03-04 15:34 |只看该作者

老虎来了,你准备好了吗?(增加for-each)

昨天说到javac竟然不能编译新语法的java文件,难道是环境每设对,先来试验一下java

  1. java -version
  2. java version "1.5.0-beta"
  3. Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-bet
  4. Java HotSpot(TM) Client VM (build 1.5.0-beta-b32c, mixed mode)
复制代码

java没问题,也就是说路径设置正确了
那试试javac

  1. Usage: javac <options>; <source files>;
  2. where possible options include:
  3.   -g                        Generate all debugging info
  4.   -g:none                   Generate no debugging info
  5.   -g:{lines,vars,source}    Generate only some debugging info
  6.   -nowarn                   Generate no warnings
  7.   -verbose                  Output messages about what the compiler is doing
  8.   -deprecation              Output source locations where deprecated APIs are used
  9.   -classpath <path>;         Specify where to find user class files
  10.   -sourcepath <path>;        Specify where to find input source files
  11.   -bootclasspath <path>;     Override location of bootstrap class files
  12.   -extdirs <dirs>;           Override location of installed extensions
  13.   -d <directory>;            Specify where to place generated class files
  14.   -encoding <encoding>;      Specify character encoding used by source files
  15.   -source <release>;         Provide source compatibility with specified release
  16.   -target <release>;         Generate class files for specific VM version
  17.   -help                     Print a synopsis of standard options
复制代码

呵呵,看出来了吗,原来有一个-source <release>; 的选项,是指定source compatibility (源代码兼容)一直都没怎么注意,想必是这里出错了.
OK,让我们再来javac一把

  1. javac -source 1.5  GenricTest.java

复制代码

什么都没提示,那就继续运行 java

  1. java GenricTest

  2. Hello World
复制代码

好了,梦寐以求的Hello World终于展现在我们面前了.我们已经成功的爬上了虎背.
4,猫和狗
Genric 当然没那么简单,它的重点在于只容纳特定类的对象.如果你读过关于集合是如何不管放进去的对象的,你也许会记得有着么一个例子(或者类似的)

....
我们往Vector里放进去了几只猫,虽然我们很清楚,这个Vector应该只有猫,但是,编译器并不提供任何的保障,一个疏忽,可能会使我们不小心就往里面扔进去一条狗
.....

那么,让我们看看,Genric是如何防止往一个给猫设计的List扔进去一条狗的,下面的例子有点复杂.


  1. //GenricTestCatAndDog.java

  2. import java.util.*;
  3. class Cat {
  4. String name;
  5. public Cat(){}
  6. public Cat(String name){
  7. this.name=name;
  8. }
  9. public void catchMouse(){
  10. //...
  11. }
  12. }
  13. class Dog{
  14. String name;
  15. public Dog(){}
  16. public Dog(String name){
  17. this.name=name;
  18. }
  19. public void bark(){
  20. //...
  21. }
  22. }
  23. public class GenricTestCatAndDog{
  24. public static void main(String args[]){
  25. Vector<Cat>; v = new Vector<Cat>;();
  26. Cat cat = new Cat("Jacky");
  27. Dog dog = new Dog("Mike");
  28. v.add(cat);
  29. v.add(dog);
  30. System.out.println(v.get(0));
  31. System.out.println(v.get(1));
  32. }
  33. }
复制代码

保存,再javac之

  1. javac -source 1.5 GenricTestCatAndDog.java

  2. GenricTestCatAndDog.java:30: cannot find symbol
  3. symbol  : method add(Dog)
  4. location: class java.util.Vector<Cat>;
  5. v.add(dog);
  6. ^
  7. 1 error
复制代码


正如我们所看到的,dog不能被放到Vector<Cat>;里面.
我们试着把放进去Dog的代码注释掉,再编译,通过了.
现在猫可以高高兴兴的在自己的窝里睡觉,不用担心狗跑来骚扰了.而我们从猫窝里抓出来得动物,也不用再去检查一下是否是猫,直接就可以命令他去抓老鼠(catchMouse)了

  1. //GenricTestCatAndDog2.java

  2. import java.util.*;
  3. class Cat {
  4. String name;
  5. public Cat(){}
  6. public Cat(String name){
  7. this.name=name;
  8. }
  9. public void catchMouse(){
  10. System.out.println((name==null?"I am ":name+" is ")+" catching mouse.... ");
  11. //...
  12. }
  13. }
  14. class Dog{
  15. String name;
  16. public Dog(){}
  17. public Dog(String name){
  18. this.name=name;
  19. }
  20. public void bark(){
  21. //...
  22. }
  23. }
  24. public class GenricTestCatAndDog2{
  25. public static void main(String args[]){
  26. Vector<Cat>; v = new Vector<Cat>;();
  27. Cat cat = new Cat("Jacky");
  28. Dog dog = new Dog("Mike");
  29. v.add(cat);
  30. //v.add(dog);
  31. v.get(0).catchMouse();
  32. }
  33. }
复制代码

编译并运行

  1. javac -source 1.5 GenricTestCatAndDog2.java

  2. java  GenricTestCatAndDog2
  3. Jacky is  catching mouse....
复制代码


让我们先休息一下,好好看看我们的猫捉会老鼠,明天回来,继续骑虎之旅.....

论坛徽章:
0
7 [报告]
发表于 2004-03-04 16:04 |只看该作者

老虎来了,你准备好了吗?(增加for-each)

几点说明:
1.文章写的比较随意,基本上是边写边改边发表,所以有错误在所难免,请大家多提意见

2.虽然可能不少读者是初学者,但是里面的很多概念也没法一一说明,大家可以参考精华区( http://www.chinaunix.net/jh/26/ ),也欢迎随时在论坛( http://bbs.chinaunix.net/forum/viewforum.php?f=26 )里发问.

3.呵呵,如果觉得不错,欢迎转载,不过请注明 来自 rollingpig @ ChinaUnix.net

4.欢迎与我探讨,
站内短信 : http://bbs.chinaunix.net/forum/privmsg.php?mode=post&u=31634
邮件 : rollingpig@163.com
Msn : rollingpig@163.com

论坛徽章:
0
8 [报告]
发表于 2004-03-05 12:24 |只看该作者

老虎来了,你准备好了吗?(增加for-each)

Genric兼容性

我们已经见识了Genric带来的好处,特定Collection/Map只能容纳特定类型的对象,取出来时不需要Cast.
但是,我们毕竟需要使用以前的某些程序.那么,新语法对以前的代码有没有影响呢.让我们用新的javac编译一下以前的这一段代码:

  1. //GenricTest2.java
  2. import java.util.*;
  3. public class GenricTest2{
  4. public static void main(String args[]){
  5. Vector v = new Vector();
  6. v.add("Helo World");
  7. String s = (String)v.get(0);
  8. System.out.println(s);
  9. }
  10. }
复制代码


  1. javac -source 1.5 GenricTest2.java

  2. Note: GenricTest2.java uses unchecked or unsafe operations.
  3. Note: Recompile with -Xlint:unchecked for details.

复制代码

ok,javac的内部参数都出来了,继续编译

  1. javac -source 1.5 -Xlint:unchecked GenricTest2.java

  2. GenricTest2.java:5: warning: [unchecked] unchecked call to add(E) as a member of the raw type java.util.Vector
  3. v.add("Helo World");
  4. ^
  5. 1 warning
复制代码

看出来了,这就象以前的 -deprecation 参数,给你一些提示.当然,原来的代码还是能继续使用的.  

创建自己的Genric类

根据前面的介绍,对于Genric,大家应该已经有所了解.那么,我们能不能创建自己的包含Genric特性的类呢?
让我们去看看Vector.java的源代码,看看它是如何做到的.然后,我们就可以依样画葫芦了;
大家都知道,jsdk发布时,通常都附带源代码.打开C:\j2sdk1.5.0,src.zip就放在那里,解开,打开java\util\Vector.java.

源码挺长,我就只列出它的重要部分(类定义,默认构造函数,add方法)
....
public class Vector<E>;
    extends AbstractList<E>;
    implements List<E>;, RandomAccess, Cloneable, java.io.Serializable
.....
public Vector() {
        this(10);
    }
    public Vector(int initialCapacity) {
        this(initialCapacity, 0);
    }
   public Vector(int initialCapacity, int capacityIncrement) {
   super();
   ...
        public void add(E o) {
            checkForComodification();

            try {
                AbstractList.this.add(cursor++, o);
                lastRet = -1;
                expectedModCount = modCount;
            } catch(IndexOutOfBoundsException e) {
                throw new ConcurrentModificationException();
            }
        }
    }
....
)

当然,还得看看它的父类(AbstractList)以及祖父类(AbstractCollection),它们的默认构造函数都是空白.
同时,可以看到,add方法出现了"<E>;"里的E.

ok,画一个葫芦先


  1. //MyGenricGun.java
  2. //子弹
  3. class Bulltin
  4. {
  5.         int damage;
  6.         public Bulltin(){};
  7. };
  8. //普通子弹
  9. class SmallBulltin extends Bulltin
  10. {
  11.        
  12.         public SmallBulltin(){damage=10;};
  13. };
  14. //火箭炮
  15. class Rocket extends Bulltin
  16. {
  17.         public Rocket(){damage=2000;};
  18. };

  19. //可以指定放子弹类型的Gun
  20. public class MyGenricGun<MyType extends Bulltin>;{

  21. //上子弹
  22. public void addBulltin(MyType bulletin){
  23.         System.out.println("add a bulletin,damage is " + bulletin.damage);
  24. //....
  25. }

  26. public static void main(String args[]){
  27. //放小子弹的枪
  28. MyGenricGun<SmallBulltin>; gun1 = new   MyGenricGun<SmallBulltin>;();
  29. //放火箭炮的枪
  30. MyGenricGun<Rocket>; gun2 = new   MyGenricGun<Rocket>;();
  31. //什么子弹都能放的枪
  32. MyGenricGun<Bulltin>; gun3 = new   MyGenricGun<Bulltin>;();
  33. //什么都能放的枪
  34. MyGenricGun gun4 = new   MyGenricGun();
  35. //什么都能放的枪
  36. //MyGenricGun<Object>; gun5 = new   MyGenricGun<Object>;();//不成功
  37. gun1.addBulltin(new SmallBulltin());
  38. //gun1.addBulltin(new Rocket());//不成功
  39. //gun2.addBulltin(new SmallBulltin());//不成功
  40. gun2.addBulltin(new Rocket());
  41. gun3.addBulltin(new Bulltin());
  42. gun3.addBulltin(new Rocket());
  43. gun3.addBulltin(new SmallBulltin());
  44. gun4.addBulltin(new SmallBulltin());
  45. gun4.addBulltin(new Rocket());
  46. gun4.addBulltin(new Bulltin());
  47. //gun4.addBulltin(new Integer(1));//不成功
  48. }

  49. }
复制代码


大家可以把标有"//不成功"的地方的注释去掉/加上,对比一下编译结果,就可以大概知道Genric的运行逻辑了.

自己再琢磨琢磨,看看java.util里的Colletion及Map FrameWork里的包,Genric暂时就说到这里.

下周,将为大家继续带来 Tiger的其他新特性(Auto Boxing unBoxing,Enhanced for loop,Enumerated types等)

论坛徽章:
0
9 [报告]
发表于 2004-03-05 16:10 |只看该作者

老虎来了,你准备好了吗?(增加for-each)

wait...

论坛徽章:
0
10 [报告]
发表于 2004-03-06 01:19 |只看该作者

老虎来了,你准备好了吗?(增加for-each)

呵呵,滚猪老大真不错,码了不少字。

1.5的Generic可能取之于Eiffel吧。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP