4.JAVA编程思想——控制程序流程

欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/51040228

控制程序流程

 

在Java 里,我们利用运算符操纵对象和数据,并用执行控制语句作出选择。Java 是建立在C++基础上的,所以对C 和C++程序员来说,对Java 这方面的大多数语句和运算符都应是非常熟悉的。当然,Java 也进行了自己的一些改进与简化工作。

 

1      使用 Java 运算符

加号(+)、减号和负号(-)、乘号(*)、除号(/)以及等号(=)的用法与其他所有编程语言都是类似的。

 

算术运算举例如下:

class Number {

 inti;

}

 

publicclass test {

 publicstaticvoid main(String[] args) {

   Number n1 =new Number();

   Number n2 =new Number();

   n1.i = 9;

   n2.i = 47;

   System.out.println("1: n1.i: " + n1.i +

     ",n2.i: " +n2.i);

   n1 =n2;

   System.out.println("2: n1.i: " + n1.i +

     ",n2.i: " +n2.i);

   n1.i = 27;

   System.out.println("3: n1.i: " + n1.i +

     ",n2.i: " +n2.i);

 }

}

Number类非常简单,它的两个实例(n1 和n2)是在main()里创建的。每个Number 中的i值都赋予了一个不同的值。随后,将n2 赋给n1,而且n1 发生改变。

输出如下:

1:n1.i: 9, n2.i: 47

2:n1.i: 47, n2.i: 47

3:n1.i: 27, n2.i: 27

再来看下方法调用中的别名处理:

class Letter {

 charc;

}

 

publicclass test {

 staticvoid f(Lettery) {

   y.c ='z';

 }

 publicstaticvoid main(String[] args) {

   Letter x =new Letter();

   x.c ='a';

   System.out.println("1: x.c: " + x.c);

   f(x);

   System.out.println("2: x.c: " + x.c);

 }

}

f()方法表面上似乎要在方法的作用域内制作自己的自变量Letter y 的一个副本。

实际传递的是一个句柄。所以下面这个程序行:

y.c = 'z'; 实际改变的是f()之外的对象。输出结果如下:

输出如下:

1:x.c: a

2: x.c: z

         

2      算术运算符

Java 的基本算术运算符与其他大多数程序设计语言是相同的。其中包括加号(+)、减号(-)、除号(/)、乘号(*)以及模数(%,从整数除法中获得余数)。整数除法会直接砍掉小数,而不是进位。 Java也用一种简写形式进行运算,并同时进行赋值操作。这是由等号前的一个运算符标记的,而且对于语言中的所有运算符都是固定的。例如,为了将4 加到变量x,并将结果赋给x,可用:x+=4。

 

示例如下:

import java.util.*;

 

publicclass test {

 //Create a shorthand to save typing:

 staticvoid prt(Strings) {

   System.out.println(s);

 }

 //shorthand to print a string and anint:

 staticvoid pInt(Strings,inti) {

   prt(s +" = " +i);

 }

 //shorthand to print a string and a float:

 staticvoid pFlt(Strings,floatf) {

   prt(s +" = " +f);

 }

 publicstaticvoid main(String[] args) {

   //Create a random number generator,

        // seeds with current time by default:

        Random rand =new Random();

        inti,j,k;

        // '%' limits maximum value to 99:

        j =rand.nextInt() % 100;

        k =rand.nextInt() % 100;

        pInt("j",j); pInt("k",k);

        i =j +k;pInt("j + k",i);

        i =j -k;pInt("j - k",i);

        i =k /j;pInt("k / j",i);

        i =k *j;pInt("k * j",i);

        i =k %j;pInt("k % j",i);

        j %=k;pInt("j %= k",j);

        // Floating-point number tests:

        floatu,v,w//applies to doubles, too

        v =rand.nextFloat();

        w =rand.nextFloat();

        pFlt("v",v);pFlt("w",w);

        u =v +w;pFlt("v + w",u);

        u =v -w;pFlt("v - w",u);

        u =v *w;pFlt("v * w",u);

        u =v /w;pFlt("v / w",u);

        // the following also works for

        // char, byte, short,int, long,

        // and double:

        u +=v;pFlt("u += v",u);

        u -=v;pFlt("u -= v",u);

        u *=v;pFlt("u *= v",u);

        u /=v;pFlt("u /= v",u);

      }

    } ///:~

prt()方法打印一个String;pInt()先打印一个String,再打印一个int;而pFlt()先打印一个 String,再打印一个float。当然,它们最终都要用System.out.println()结尾。

为生成数字,程序首先会创建一个 Random(随机)对象。由于自变量是在创建过程中传递的,所以 Java 将当前时间作为一个“种子值”,由随机数生成器利用。通过Random 对象,程序可生成许多不同类型的随机数字。只需调用不同的方法即可:nextInt()nextLong()nextFloat()或者nextDouble()

若随同随机数生成器的结果使用,模数运算符(%)可将结果限制到运算对象减1的上限(本例是99)之下。

输出如下:

j= -58

k= 13

j+ k = -45

j- k = -71

k/ j = 0

k* j = -754

k% j = 13

j%= k = -6

v= 0.88164216

w= 0.17560738

v+ w = 1.0572495

v- w = 0.7060348

v* w = 0.15482287

v/ w = 5.02053

u+= v = 5.9021726

u-= v = 5.02053

u*= v = 4.426311

u /= v = 5.02053

 

3      自动递增和递减

和C 类似,Java 提供了丰富的快捷运算方式。这些快捷运算可使代码更清爽,更易录入,也更易读者辨读。

两种很不错的快捷运算方式是递增和递减运算符(常称作“自动递增”和“自动递减”运算符)。其中,递减运算符是“--”,意为“减少一个单位”;递增运算符是“++”,意为“增加一个单位”。

对每种类型的运算符,都有两个版本可供选用;通常将其称为“前缀版”和“后缀版”。“前递增”表示++运算符位于变量或表达式的前面;而“后递增”表示++运算符位于变量或表达式的后面。类似地,“前递减”意味着--运算符位于变量或表达式的前面;而“后递减”意味着--运算符位于变量或表达式的后面。对于前递增和前递减(如++A或--A),会先执行运算,再生成值。而对于后递增和后递减(如A++或A--),会先生成值,再执行运算。下面是一个例子:

publicclass test {

 publicstaticvoid main(String[] args) {

   inti = 1;

   prt("i : " +i);

   prt("++i : " + ++i);// Pre-increment

   prt("i++ : " +i++);// Post-increment

   prt("i : " +i);

   prt("--i : " + --i);// Pre-decrement

   prt("i-- : " +i--);// Post-decrement

   prt("i : " +i);

 }

 staticvoid prt(Strings) {

   System.out.println(s);

 }

} ///:~

输出如下:

i: 1

++i: 2

i++: 2

i: 3

--i: 2

i--: 2

i : 1

 

4      关系运算符

关系运算符生成的是一个“布尔”(Boolean)结果。它们评价的是运算对象值之间的关系。若关系是真实的,关系表达式会生成 true(真);若关系不真实,则生成false(假)。关系运算符包括小于(<)、大于(>)、小于或等于(<=)、大于或等于(>=)、等于(==)以及不等于(!=)。等于和不等于适用于所有内建的数据类型,但其他比较不适用于boolean类型。

示例如下:

publicclass test {

 publicstaticvoid main(String[] args) {

   Integer n1 =new Integer(47);

   Integer n2 =new Integer(47);

   System.out.println(n1 == n2);

    System.out.println(n1 != n2);

  }

} ///:~

输出如下:

false

true

达式System.out.println(n1== n2)可打印出内部的布尔比较结果。一般人都会认为输出结果肯定先是true,再是 false,因为两个Integer 对象都是相同的。但尽管对象的内容相同,句柄却是不同的,而==和!=比较的正好就是对象句柄。所以输出结果实际上先是false,再是 true。

若想对比两个对象的实际内容是否相同,又该如何操作呢?此时,必须使用所有对象都适用的特殊方法equals()。但这个方法不适用于“主类型”,那些类型直接使用==和!=即可。

 

5      逻辑运算符

逻辑运算符 AND(&&)、OR(||)以及 NOT(!)能生成一个布尔值(true 或false)——以自变量的逻辑关系为基础。下面这个例子向大家展示了如何使用关系和逻辑运算符。

 

示例如下:

import java.util.*;

 

publicclass test {

 publicstaticvoid main(String[] args) {

   Random rand =new Random();

   inti =rand.nextInt() % 100;

   intj =rand.nextInt() % 100;

   prt("i = " +i);

   prt("j = " +j);

   prt("i > j is " + (i > j));

   prt("i < j is " + (i < j));

   prt("i >= j is " + (i >= j));

   prt("i <= j is " + (i <= j));

   prt("i == j is " + (i == j));

   prt("i != j is " + (i != j));

 

   //Treating anint as a boolean is 

   // notlegal Java

//! prt("i && jis " + (i && j));

//! prt("i || j is "+ (i || j));

//! prt("!i is " +!i);

 

   prt("(i < 10) && (j < 10) is "

      + ((i < 10) && (j < 10)) );

   prt("(i < 10) || (j < 10) is "

      + ((i < 10) || (j < 10)) );

 }

 staticvoid prt(Strings) {

   System.out.println(s);

 }

} ///:~

 

6      按位运算符

按位运算符允许我们操作一个整数主数据类型中的单个“比特”,即二进制位。按位运算符会对两个自变量中对应的位执行布尔代数,并最终生成一个结果。

按位运算来源于C 语言的低级操作。我们经常都要直接操纵硬件,需要频繁设置硬件寄存器内的二进制位。

Java 的设计初衷是嵌入电视顶置盒内,所以这种低级操作仍被保留下来了。然而,由于操作系统的进步,现在也许不必过于频繁地进行按位运算。

若两个输入位都是1,则按位AND 运算符(&)在输出位里生成一个 1;否则生成0。若两个输入位里至少有一个是1,则按位OR运算符(|)在输出位里生成一个 1;只有在两个输入位都是0 的情况下,它才会生成一个0。若两个输入位的某一个是1,但不全都是1,那么按位 XOR(^,异或)在输出位里生成一个1。按位NOT(~,也叫作“非”运算符)属于一元运算符;它只对一个自变量进行操作(其他所有运算符都是二元运算符)。按位NOT生成与输入位的相反的值——若输入 0,则输出1;输入1,则输出0。

按位运算符和逻辑运算符都使用了同样的字符,只是数量不同。因此,我们能方便地记忆各自的含义:由于“位”是非常“小”的,所以按位运算符仅使用了一个字符。

按位运算符可与等号(=)联合使用,以便合并运算及赋值:&=,|=和^=都是合法的(由于~是一元运算符,所以不可与=联合使用)。

我们将boolean(布尔)类型当作一种“单位”或“单比特”值对待,所以它多少有些独特的地方。我们可执行按位AND,OR和XOR,但不能执行按位 NOT(大概是为了避免与逻辑NOT混淆)。对于布尔值,按位运算符具有与逻辑运算符相同的效果,只是它们不会中途“短路”。此外,针对布尔值进行的按位运算为我们新增了一个XOR逻辑运算符,它并未包括在“逻辑”运算符的列表中。在移位表达式中,我们被禁止使用布尔运算。

 

7      移位运算符

移位运算符面向的运算对象也是二进制的“位”。可单独用它们处理整数类型(主类型的一种)。左移位运算符(<<)能将运算符左边的运算对象向左移动运算符右侧指定的位数(在低位补 0)。“有符号”右移位运算符(>>)则将运算符左边的运算对象向右移动运算符右侧指定的位数。“有符号”右移位运算符使用了“符号扩展”:若值为正,则在高位插入0;若值为负,则在高位插入1。Java也添加了一种“无符号”右移位运算符(>>>),它使用了“零扩展”:无论正负,都在高位插入0。这一运算符是CC++没有的。

若对char,byte 或者short 进行移位处理,那么在移位进行之前,它们会自动转换成一个int。只有右侧的5个低位才会用到。这样可防止我们在一个 int数里移动不切实际的位数。若对一个long 值进行处理,最后得到的结果也是long。此时只会用到右侧的 6个低位,防止移动超过 long 值里现成的位数。但在进行“无符号”右移位时,也可能遇到一个问题。若对byte 或short 值进行右移位运算,得到的可能不是正确的结果(Java 1.0 和Java 1.1 特别突出)。它们会自动转换成int 类型,并进行右移位。但“零扩展”不会发生,所以在那些情况下会得到-1 的结果。

publicclass test {

      publicstaticvoid main(String[] args) {

            inti = -1;

            i >>>= 10;

            System.out.println(i);

            longl = -1;

            l >>>= 10;

            System.out.println(l);

            shorts = -1;

            s >>>= 10;

            System.out.println(s);

            byteb = -1;

            b >>>= 10;

            System.out.println(b);

          }

        } ///:~

输出:

4194303

18014398509481983

-1

-1

移位可与等号(<<=或>>=或>>>=)组合使用。此时,运算符左边的值会移动由右边的值指定的位数,再将得到的结果赋回左边的值。

 

8      造型运算符

“造型”(Cast)的作用是“与一个模型匹配”。在适当的时候,Java 会将一种数据类型自动转换成另一种。例如,假设我们为浮点变量分配一个整数值,计算机会将 int自动转换成 float。通过造型,我们可明确设置这种类型的转换,或者在一般没有可能进行的时候强迫它进行。 为进行一次造型,要将括号中希望的数据类型(包括所有修改符)置于其他任何值的左侧。

正如您看到的那样,既可对一个数值进行造型处理,亦可对一个变量进行造型处理。但在这儿展示的两种情况下,造型均是多余的,因为编译器在必要的时候会自动进行 int值到long 值的转换。当然,仍然可以设置一个造型,提醒自己留意,也使程序更清楚。在其他情况下,造型只有在代码编译时才显出重要性。在C 和C++中,造型有时会让人头痛。

在Java 里,造型则是一种比较安全的操作。但是,若进行一种名为“缩小转换”(Narrowing Conversion)的操作(也就是说,脚本是能容纳更多信息的数据类型,将其转换成容量较小的类型),此时就可能面临信息丢失的危险。此时,编译器会强迫我们进行造型,就好象说:“这可能是一件危险的事情——如果您想让我不顾一切地做,那么对不起,请明确造型。”而对于“放大转换”(Widening conversion),则不必进行明确造型,因为新类型肯定能容纳原来类型的信息,不会造成任何信息的丢失。

Java 允许我们将任何主类型“造型”为其他任何一种主类型,但布尔值(bollean)要除外,后者根本不允许进行任何造型处理。“类”不允许进行造型。为了将一种类转换成另一种,必须采用特殊的方法(字串是一种特殊的情况,本书后面会讲到将对象造型到一个类型“家族”里;例如,“橡树”可造型为“树”;反之亦然。但对于其他外来类型,如“岩石”,则不能造型为“树”)。

 

9      Java 没有“sizeof ”

在C 和C++中,sizeof()运算符能满足我们的一项特殊需要:获知为数据项目分配的字符数量。在C 和C++中,size()最常见的一种应用就是“移植”。不同的数据在不同的机器上可能有不同的大小,所以在进行一些对大小敏感的运算时,程序员必须对那些类型有多大做到心中有数。例如,一台计算机可用32位来保存整数,而另一台只用16位保存。显然,在第一台机器中,程序可保存更大的值。正如您可能已经想到的那样,移植是令C 和C++程序员颇为头痛的一个问题。

Java 不需要sizeof()运算符来满足这方面的需要,因为所有数据类型在所有机器的大小都是相同的。我们不必考虑移植问题——Java 本身就是一种“与平台无关”的语言。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值