1. Java基本的程序设计结构

来源:互联网 发布:大数据300 - 百度 编辑:程序博客网 时间:2024/06/10 12:23

1.1 一个简单的Java应用程序

public class FirstSample {

pulbic static void main(String args[]) {

System.out.println("We will not use 'Hello World !'");

}

}

main 方法是让你从java以外的环境启动java程序的入口函数,就像C/C++也用main作为入口函数一样,当我们从命令行运行 java ClassName 的时候,jvm 就从这个ClassName的main方法开始执行。jvm运行程序时因为还没有创建对象要从静态函数执行,所以要加关键字static。String args[] 接受从命令行传递过来的参数。


1.2 变量

由于基本变量,String等已经十分熟悉。

对于String这里说一点,不可变字符串有一个优点:编译器可以将字符串共享。

这里只介绍枚举Enum变量。

枚举是Tiger(Java5.0)的一个很重要的新特性,它是一种新的类型,允许用常量来表示特定的数据片断,而且全部都以类型安全的形式来表示,它使用“enum”关键字来定义。

我们先来写一个简单的枚举类型的定义:

public enum WeekDay{
         MONDAY, TUESDAY, WENSDAY, THURSDAY, FRIDAY; //最后这个“;”可写可不写。
}

这和类、接口的定义很相像嘛!Tiger中的枚举类型就是一种使用特殊语法“enum”定义的类。所有的枚举类型是java.lang.Enum的子类。这是Tiger中新引入的一个类,它本身并不是枚举类型,但它定义了所有枚举类型所共有的行为,如下表:



注意:虽然所有的枚举类型都继承自java.lang.Enum,但是你不能绕过关键字“enum”而使用直接继承Enum的方式来定义枚举类型。编译器会提示错误来阻止你这么做。

WeekDay中定义的五个枚举常量之间使用“,”分割开来。这些常量默认都是“public static final”的,所以你就不必再为它们加上“public static final”修饰(编译器会提示出错),这也是为什么枚举常量采用大写字母来命名的原因。而且每一个常量都是枚举类型WeekDay的一个实例。你可以通过类似“WeekDay.MONDAY”这种格式来获取到WeekDay中定义的枚举常量,也可以采用类似“WeekDay oneDay = WeekDay.MONDAY”的方式为枚举类型变量赋值(你不能给枚举类型变量分配除了枚举常量和null以外的值,编译器会提示出错)。

作为枚举类型实例的枚举常量是如何初始化的呢?其实答案很简单,这些枚举常量都是通过Enum中定义的构造函数进行初始化的。

//java.lang.Enum中定义的构造函数,
//两个参数分别是定义的枚举常量名称以及它所在的次序。
protected Enum(String name, int ordinal) {
       this.name = name;
       this.ordinal = ordinal;
}

在初始化的过程中,枚举常量的次序是按照声明的顺序安排的。第一个枚举常量的次序是0,依此累加。

枚举类型除了拥有Enum提供的方法以外,还存在着两个隐藏着的与具体枚举类型相关的静态方法——values()和valueOf(String arg0)。方法values()可以获得包含所有枚举常量的数组;方法valueOf是java.lang.Enum中方法valueOf的简化版本,你可以通过它,根据传递的名称来得到当前枚举类型中匹配的枚举常量。


Enum作为Sun全新引进的一个关键字,看起来很象是特殊的class,    它也可以有自己的变量,可以定义自己的方法,可以实现一个或者多个接口。    当我们在声明一个enum类型时,我们应该注意到enum类型有如下的一些特征。     
     1.它不能有public的构造函数,这样做可以保证客户代码没有办法新建一个enum的实例。     
     2.所有枚举值都是public    ,    static    ,    final的。注意这一点只是针对于枚举值,我们可以和在普通类里面定义    变量一样定义其它任何类型的非枚举变量,这些变量可以用任何你想用的修饰符。     
     3.Enum默认实现了java.lang.Comparable接口。     
     4.Enum覆载了了toString方法,因此我们如果调用Color.Blue.toString()默认返回字符串”Blue”.     
     5.Enum提供了一个valueOf方法,这个方法和toString方法是相对应的。调用valueOf(“Blue”)将返回Color.Blue.因此我们在自己重写toString方法的时候就要注意到这一点,一把来说应该相对应地重写valueOf方法。     
     6.Enum还提供了values方法,这个方法使你能够方便的遍历所有的枚举值。         
     7.Enum还有一个oridinal的方法,这个方法返回枚举值在枚举类种的顺序,这个顺序根据枚举值声明的顺序而定,这里Color.Red.ordinal()返回0。     
     

   了解了这些基本特性,我们来看看如何使用它们。     
    
     1.遍历所有有枚举值.    知道了有values方法,我们可以轻车熟路地用ForEach循环来遍历了枚举值了。     
     for    (Color    c:    Color.values())     
     System.out.println(“find    value:”    +    c);     
    
     2.在enum中定义方法和变量,比如我们可以为Color增加一个方法随机返回一个颜色。     
     public    enum    Color    {     
     Red,     
     Green,     
     Blue;     
    
     /*     
     *定义一个变量表示枚举值的数目。     
     *(我有点奇怪为什么sun没有给enum直接提供一个size方法).     
     */     
     private    static    int    number    =    Color.values().length    ;     
    
     /**     
     *    随机返回一个枚举值     
     @return    a    random    enum    value.     
     */     
     public    static    Color    getRandomColor(){     
     long    random    =    System.currentTimeMillis()    %    number;     
     switch    ((int)    random){     
      case    0:     
       return    Color.Red;     
      case    1:     
       return    Color.Green;     
      case    2:     
       return    Color.Blue;     
      default    :    return    Color.Red;     
     }     
     }     
     }     
    
     可以看出这在枚举类型里定义变量和方法和在普通类里面定义方法和变量没有什么区别。唯一要注意的只是变量和方法定义必须放在所有枚举值定义的后面,否则编译器会给出一个错误。     
    
     3.覆载(Override)toString,    valueOf方法     
    
     前面我们已经知道enum提供了toString,valueOf等方法,很多时候我们都需要覆载默认的toString方法,那么对于enum我们怎么做呢。其实这和覆载一个普通class的toString方法没有什么区别。     
    
     ….     
     public    String    toString(){     
     switch    (this){     
     case    Red:     
      return    "Color.Red";     
     case    Green:     
      return    "Color.Green";     
     case    Blue:     
      return    "Color.Blue";     
     default:     
      return    "Unknow    Color";     
     }     
     }     
     ….     
    
     这时我们可以看到,此时再用前面的遍历代码打印出来的是     
    
     Color.Red     
     Color.Green     
     Color.Blue     
    
     而不是     
    
     Red     
     Green     
     Blue.     
    
     可以看到toString确实是被覆载了。一般来说在覆载toString的时候我们同时也应该覆载valueOf方法,以保持它们相互的一致性。     
    
     4.使用构造函数     
    
     虽然enum不可以有public的构造函数,但是我们还是可以定义private的构造函数,在enum内部使用。还是用Color这个例子。     
    
     public    enum    Color    {     
     Red("This    is    Red"),     
     Green("This    is    Green"),     
     Blue("This    is    Blue");     
    
     private    String    desc;     
    
     Color(String    desc){     
     this.desc    =    desc;     
     }     
    
     public    String    getDesc(){     
     return    this.desc;     
     }     
    
     }     
    
     这里我们为每一个颜色提供了一个说明信息,    然后定义了一个构造函数接受这个说明信息。     
    
     要注意这里构造函数不能为public或者protected,    从而保证构造函数只能在内部使用,客户代码不能new一个枚举值的实例出来。这也是完全符合情理的,因为我们知道枚举值是public    static    final的常量而已。     
    
     5.实现特定的接口     
    
     我们已经知道enum可以定义变量和方法,它要实现一个接口也和普通class实现一个接口一样,这里就不作示例了。     
    
     6.定义枚举值自己的方法。     
    
     前面我们看到可以为enum定义一些方法,其实我们甚至可以为每一个枚举值定义方法。这样,我们前面覆载    toString的例子可以被改写成这样。     
    
     public    enum    Color    {     
     Red    {     
     public    String    toString(){     
      return    "Color.Red";     
     }     
     },     
     Green    {     
     public    String    toString(){     
      return    "Color.Green";     
     }     
     },     
     Blue{     
     public    String    toString(){     
      return    "Color.Blue";     
     }     
     };     
     }     


1.3 读取输入


要想通过控制台进行输入,首先要构造一个Scanner对象。它附属于标准输入流 System.in。

Scanner in = new Scanner(System.in);

现在就可以用Scanner的各种方法进行操作了。例如nextLine方法将输入一行。

System.out.println("what's your name?");

in.nextLine();

在这里,使用nextLine方法的主要原因是输入行中可能包含空格。如果读取的是一个单词(以空白符作为分隔符),则可以调用:

String firstName = in.next();

如果要读取一个整数,可以使用nextInt()方法:

int age = in.nextInt();

与此类似,要想读取下一个浮点数,可以使用nextDouble方法。

最后,在程序的开始那一行加上java.util.*;

此外,Scanner类还有以下方法:

boolean hasNext(): 测试输入中是否还有单词。

boolean hasNextInt ,boolean hasNextDouble: 测试是否还有表示整数或者浮点数的下个字符序列。