Java Passion

Tuesday Apr 08, 2008

Java SE 5 语言功能增强 (二)

练习 4:可变参数


在以前的版本中,获取任意数量的值的方法需要在调用该方法前,创建一个数组,并将这些值放到此数组中。例如,以下是过去如何使用 MessageFormat 类对消息进行格式化:
Object[] arguments = {
    new Integer(7),
    new Date(),
    "a disturbance in the Force"
};

String result = MessageFormat.format(
    "At {1,time} on {1,date}, there was {2} on planet " + "{0,number,integer}.",
    arguments);   // arguments is an array

目前仍然必须将多参数传入到数组中,但可变参数功能将这一过程自动化并隐藏起来。而且,它向上兼容于以前存在的 API。所以,例如 MessageFormat.format 方法现在有如下声明:
public static String format(String pattern, Object... arguments);

跟在最后一个参数类型后面的三个句点表示,最后一个参数可能被当作数组或参数序列进行传递。可变参数只可被用在最后一个参数的位置。鉴于 MessageFormat.format 的新的可变参数声明,以上调用可以被下列更为简短易用的调用所取代:
String result = MessageFormat.format(
    "At {1,time} on {1,date}, there was {2} on planet " + "{0,number,integer}.",
    7, new Date(), "a disturbance in the Force"); // varargs

      (4.1)未使用可变参数的示例


      1. 创建一个新的 NetBeans 项目
      • 选择 文件->新建项目(Ctrl+Shift+N)。此时将出现 新建项目 对话框。
      • 选择项目 窗格中,选择 类别 列表中的 Java,并选择 项目 列表中的 Java 应用程序。单击 下一步 按钮。
      • 名称和位置 窗格中的 项目名称 字段中键入 NotUsingVarArgs 作为项目名。
      • 创建主类 字段中键入 NotUsingVarArgs
      • 单击 完成 按钮。
      • 注意到出现了 NotUsingVarArgs 项目,由 IDE 生成的 NotUsingVarArgs.java 显示于 NetBeans IDE 的源编辑器窗口中。
      2. 根据代码 4.11 修改由 IDE 生成的 NotUsingVarArgs.java。仔细阅读该代码,需要特别注意粗体部分。
      import java.util.Date;
      import java.text.MessageFormat;
      import java.util.*;

      public class NotUsingVarArgs {
         
          public String formatThis(){
             
              Object[] args = {
                  "Hurricane",
                  new Integer( 99 ),
                  new GregorianCalendar( 1999, 0, 1).getTime(),
                  new Double( 10E7 )     };
             
              return MessageFormat.format( "On {2}, a {0} destroyed {1} houses and caused {3} of damage",
                      args );
          }
         
          public static void main( String[] args ){
             
              NotUsingVarArgs v = new NotUsingVarArgs();
              System.out.println( v.formatThis());
             
          }
      }
      代码 4.11:NotUsingVarArgs.java

      3. 生成和运行项目
      • 右键单击 NotUsingVarArgs 项目并选择 运行
      • 在 IDE 的输出窗口中查看结果。(如图 4.13 所示)
      On 1/1/99 12:00 AM, a Hurricane destroyed 99 houses and caused 100,000,000 of damage
      图 4.13:结果

                                                                                                                    返回练习顶部

      (4.2)使用可变参数的示例


      1. 创建一个新的 NetBeans 项目
      • 选择 文件->新建项目(Ctrl+Shift+N)。此时将出现 新建项目 对话框。
      • 选择项目 窗格中,选择 类别 列表中的 Java,并选择 项目 列表中的 Java 应用程序。单击 下一步 按钮。
      • 名称和位置 窗格中的 项目名称 字段中键入 UsingVarArgs 作为项目名。
      • 创建主类 字段中键入 UsingVarArgs
      • 单击 完成 按钮。
      • 注意到出现了 UsingVarArgs 项目,由 IDE 生成的 UsingVarArgs.java 显示于 NetBeans IDE 的源编辑器窗口中。
      2. 根据代码 4.21 修改由 IDE 生成的 UsingVarArgs.java。仔细阅读该代码,需要特别注意粗体部分。
      import java.util.Date;
      import java.text.MessageFormat;
      import java.util.*;

      public class UsingVarArgs {
          public UsingVarArgs(){ }

          public String formatThis(){

              return( MessageFormat.format( "On {2}, a {0} destroyed {1} houses and caused {3} of damage",
                                                            "Hurricane",
                                                            new Integer( 99 ),
                                                            new GregorianCalendar( 1999, 0, 1).getTime(),
                                                            new Double( 10E7 )));
          }

          public static void main( String[] args ){

              UsingVarArgs v = new UsingVarArgs();
              System.out.println( v.formatThis());

          }
      }
      代码 4.21:UsingAutoBoxging.java

      3. 生成和运行项目
      • 右键单击 UsingVarArgs 项目并选择 运行
      • 在 IDE 的输出窗口中查看结果。(如图 4.23 所示)
      On 1/1/99 12:00 AM, a Hurricane destroyed 99 houses and caused 100,000,000 of damage
      图 4.23:结果


                                                                                                                    返回练习顶部

      结束语


      在本练习中,您了解了如何使用 J2SE 5.0 的可变参数功能



                                                                                                                          返回顶部

      练习 5:类型安全枚举


        在之前的 J2SE 5.0 中,表示枚举类型的标准方法是 "int 枚举模式",如下所示:
        // int Enum Pattern - has severe problems!
        public static final int SEASON_WINTER = 0;
        public static final int SEASON_SPRING = 1;
        public static final int SEASON_SUMMER = 2;
        public static final int SEASON_FALL   = 3;

        此模式存在许多问题,如下所示:
        • 非类型安全 —— 季节只是一个 int 类型,您可以在需要季节时传入任意其他 int 值,或一起添加两个季节(这没有意义)。
        • 无命名空间 —— 您必须为 "int 枚举" 的常量加上一个字符串(本例中为 SEASON_)作为前缀,以避免和其他 int 枚举类型相冲突。
        • 脆弱性 —— 由于 int 枚举值是编译时常量,所以它们被编译到使用它们的应用程序中。如果在两个已有常量间添加新常量或改变顺序,就必须重新编译应用程序。如果不这样做,应用程序仍将运行,但其行为是未定义的。
        • 输出值信息量不足 —— 由于它们只是 int 值,如果输出一个,您所得到的只是一个数字,并不能表示它代表什么,甚至不能表示它的类型。
        可以通过使用类型安全枚举模式(参见 Effective Java 第 21 条)来解决这些问题,但此模式有其自身的问题:它相当繁琐,因而容易出错,并且它的 enum 常量不能用于 switch 语句。
        类型安全枚举(enum)允许用任意方法或字段创建枚举类型。它具有类型安全枚举模式(参见 "Effective Java",第 21 条)的所有优点,却并不繁琐也不容易出错。

        (5.1)未使用类型安全枚举的示例


        1. 创建一个新的 NetBeans 项目
        • 选择 文件->新建项目(Ctrl+Shift+N)。此时将出现 新建项目 对话框。
        • 选择项目 窗格中,选择 类别 列表中的 Java,并选择 项目 列表中的 Java 应用程序。单击 下一步 按钮。
        • 名称和位置 窗格中的 项目名称 字段中键入 NotUsingTypeSafeEnum 作为项目名。
        • 创建主类 字段中键入 NotUsingTypeSafeEnum
        • 单击 完成 按钮。
        • 注意到出现了 NotUsingTypeSafeEnum 项目,由 IDE 生成的 NotUsingTypeSafeEnum.java 显示于 NetBeans IDE 的源编辑器窗口中。
        2. 根据代码 5.11 修改由 IDE 生成的 NotUsingTypeSafeEnum.java。仔细阅读该代码,需要特别注意粗体部分。
        class FootballScore {
          
            public static final int EXTRAPOINT = 1;
            public static final int TWOPOINTS  = 2;
            public static final int SAFETY     = 2;
            public static final int FIELDGOAL  = 3;
            public static final int TOUCHDOWN  = 6;

            private int score;

            public FootballScore( int score ){
                this.score = score;
            }

            public FootballScore(){
                this.score = 0;
            }

            public int getScore(){
                return this.score;
            }

        }


        public class NotUsingTypeSafeEnum {
          
            public static void main( String[] args ){
                FootballScore[]  myScores = {
                    new FootballScore( FootballScore.TOUCHDOWN ),
                    new FootballScore( FootballScore.EXTRAPOINT ),
                    new FootballScore( FootballScore.FIELDGOAL ),
                    new FootballScore( FootballScore.TOUCHDOWN ),
                    new FootballScore( FootballScore.SAFETY ),
                    new FootballScore( FootballScore.TOUCHDOWN ),
                    new FootballScore( FootballScore.TWOPOINTS )
                 };

                FootballScore[] yourScores = {
                    new FootballScore( FootballScore.FIELDGOAL ),
                    new FootballScore( FootballScore.TOUCHDOWN ),
                    new FootballScore( FootballScore.FIELDGOAL )
                };


                int mytotal = calcTotal( myScores );
                int yourtotal = calcTotal( yourScores );
         
                System.out.println( " My football team scored " + mytotal );
                System.out.println( " Your football team scored " + yourtotal );
         
                if ( mytotal > yourtotal ){
                    System.out.println( " My Team Won! " );
                }
                else if ( mytotal < yourtotal ){
                    System.out.println( " Your Team Won! " );
                }
                else
                    System.out.println( "What do you know?  It is a Tie !! " );

           }

           public static int calcTotal( FootballScore[] f ){
                int total = 0;
              for ( int i = 0; i < f.length; ++i ){
                      total += f[i].getScore();
              }
              return total;
            }
        }
        代码 5.11:NotUsingTypeSafeEnum.java

        3. 生成和运行项目
        • 右键单击 NotUsingTypeSafeEnum 项目并选择 运行
        • 在 IDE 的输出窗口中查看结果。(如图 5.13 所示)
         My football team scored 26
         Your football team scored 12
         My Team Won!
        图 5.13:结果

                                                                                                                      返回练习顶部

        (5.2)使用类型安全枚举的示例


        1. 创建一个新的 NetBeans 项目
        • 选择 文件->新建项目(Ctrl+Shift+N)。此时将出现 新建项目 对话框。
        • 选择项目 窗格中,选择 类别 列表中的 Java,并选择 项目 列表中的 Java 应用程序
        • 单击 下一步 按钮。
        • 名称和位置 窗格中的 项目名称 字段中键入 UsingTypeSafeEnum 作为项目名。
        • 创建主类 字段中键入 UsingTypeSafeEnum
        • 单击 完成 按钮。
        • 注意到出现了 UsingTypeSafeEnum 项目,由 IDE 生成的 UsingTypeSafeEnum.java 显示于 NetBeans IDE 的源编辑器窗口中。
        2. 根据代码 5.12 修改由 IDE 生成的 UsingTypeSafeEnum.java。仔细阅读该代码,需要特别注意粗体部分。
        public class UsingTypeSafeEnum {
           
            // Note that FootballScore is now enum type
            public enum FootballScore {
                TOUCHDOWN( 6 ), FIELDGOAL( 3 ), TWOPOINTS( 2 ), SAFETY( 2 ), EXTRAPOINT( 1 );
               
                FootballScore( int value ){
                    this.score = value;
                }
               
                private final int score;
               
                public int score(){
                    return score;
                }
            }
           
            public static void main( String[] args ){
               
                FootballScore[] myScores = {
                    FootballScore.TOUCHDOWN,
                    FootballScore.EXTRAPOINT,
                    FootballScore.FIELDGOAL,
                    FootballScore.TOUCHDOWN,
                    FootballScore.SAFETY,
                    FootballScore.TOUCHDOWN,
                    FootballScore.TWOPOINTS
                };
               
                FootballScore[] yourScores = {
                    FootballScore.FIELDGOAL,
                    FootballScore.TOUCHDOWN,
                    FootballScore.FIELDGOAL
                };
               
               
                int mytotal = calcTotal( myScores );
                int yourtotal = calcTotal( yourScores );
               
                System.out.println( " My football team scored " + mytotal );
                System.out.println( " Your football team scored " + yourtotal );
               
                if ( mytotal > yourtotal ){
                    System.out.println( " My Team Won! " );
                } else if ( mytotal < yourtotal ){
                    System.out.println( " Your Team Won! " );
                } else
                    System.out.println( "What do you know?  It is a Tie !! " );
            }
           
            public static int calcTotal( FootballScore[] f ){
                int total = 0;
                for ( int i = 0; i < f.length; ++i ){
                   total += f[i].score();
                }
                return total;
            }
           
        }
        代码 5.21:UsingAutoBoxging.java

        3. 生成和运行项目
        • 右键单击 UsingTypeSafeEnum 项目并选择 运行
        • 在 IDE 的输出窗口中查看结果。(如图 5.23 所示)
         My football team scored 26
         Your football team scored 12
         My Team Won!
        图 5.23:结果


                                                                                                                      返回练习顶部

        结束语


        在本练习中,您了解了如何使用类型安全枚举。


                                                                                                                                返回顶部


        课外练习(针对 Sang Shin“Java EE 编程在线课程”的学习者)


        1. 课外练习是修改 练习 5 中创建的 UsingTypeSafeEnum NetBeans 项目(可通过复制 UsingTypeSafeEnum 项目来创建一个新项目)。您可以将该课外练习项目命名为任意名称,此处我将使用 MyUsingTypeSafeEnum
        • 修改 UsingTypeSafeEnum.java,从而使 FootballScore 枚举类型具有 extrapoint 字段(除了 score 字段外)。建议根据以下 H-01 所示更改代码。
        public class UsingTypeSafeEnum {
           
            // Note that FootballScore is now enum type
            public enum FootballScore {
                TOUCHDOWN( 6, 2 ), FIELDGOAL( 3, 2 ), TWOPOINTS( 2, 2 ), SAFETY( 2, 1 ), EXTRAPOINT( 1, 0 );
               
                FootballScore( int value, int extrapoint ){
                    this.score = value;
                    this.extrapoint = extrapoint;
                }

                // More code
        H-01:经过修改的 UsingTypeSafeEnum.java
        • 通过检查 score extrapoint 字段的值(而不是只考虑 score 字段),修改在 myScores youScores 之间寻找获胜者的逻辑。

        2. 将以下文件以 JavaIntro-javase5language 作为 主题 发送到 javaintro1homework@sun.com
        • MyUsingTypeSafeEnum NetBeans 项目的压缩文件。(其他人应该能够将其作为 NetBeans 项目打开并运行。) 您可以使用自己喜欢的压缩工具,或者使用 JDK 附带的 "jar" 实用工具,如下所示。
          • cd <包含 MyUsingTypeSafeEnum 目录的父目录> (假设您将项目命名为 MyUsingTypeSafeEnum
          • jar cvf MyUsingTypeSafeEnum.zip MyUsingTypeSafeEnum (MyUsingTypeSafeEnum 应包含 nbproject 目录)
        • 抓取输出屏幕  - 将其命名为 JavaIntro-javase5language.gif JavaIntro-javase5language.jpg (或 JavaIntro-javase5language <任何图片格式均可>)。
          • 抓取的屏幕截图只需显示程序正常运行即可。不需要任何修饰和美化。
        • 如果决定使用 NetBeans 之外的其他 IDE,则压缩文件应该包含重新编译项目所需的所有文件。




        原文链接:http://www.javapassion.com/handsonlabs/javase5language/index.html

        Comments:

        Post a Comment:
        • HTML Syntax: NOT allowed

        Calendar

        Feeds

        Search

        Links

        Navigation

        Referrers