THINKING IN JAVA 学习笔记(二)

第三章 操作符

3.1 更简单的打印语句

Java SE5新增静态导入static import)概念,在第六章会创建一个小类库简化打印语句的编写。现在直接使用它:

import java.util.*;
import static net.mindview.util.Print.*;

public class HelloDate() {
    public static void main(String[] args) {
        print("Hello, it's: ");
        print(new Date());
    }
}

要使用这个类库,必须下载代码包,然后解压代码目录树,并在CLASSPATH环境变量中添加该代码目录树的根目录。

3.4 赋值

赋值语句的左边必须是一个明确的、已命名的变量。例如:

a = 4;

基本类型存储了实际值,而不是指向对象的引用。所以基本类型的a=ba的内容就变成了b的内容,接者修改a不会影响b

但是假如将一个对象赋值给另一个对象,实际上是将“引用”复制过去了。所以对象使用c=d,那么cd都指向原本只有d指向的对象。

import static net.mindview.util.Print.*;

class Tank {
    int i;
}

public class Assignment {
    public static void main(String[] args) {
        Tank t1 = new Tank();
        Tank t2 = new Tank();
        t1.i = 9;
        t2.i = 47;
        print("1:"+t1.i+" "+t2.i);
        t1 = t2;
        print("2:"+t1.i+" "+t2.i);
        t1.i = 20;
        print("3:"+t1.i+" "+t2.i);
    }
} /* 输出:
1:9 47
2:47 47
3:20 20
*/

 t1 = t2; 执行后,此时t1、t2实际上都变成了 Tank t2 = new Tank(); 这条语句创建的对象的引用,而 Tank t1 = new Tank(); 语句创建的对象的引用原来是t1,现在却丢失

这种现象称作“别名现象”,是Java操作对象的一种基本方式。

3.4.1 方法调用中的别名问题

将一个对象传递给一个方法,也存在别名问题:

import static net.mindview.util.Print.*;

class Letter {
    char c;
}

public class PassObject {
    static void f(Letter y) {
    y.c = 'z';
    }
    public static void main(String[] args) {
    Letter x = new Letter();
    x.c = 'a';
    print("1: x.c: "+x.c);
    f(x);
    print("2: x.c: "+x.c);
    }
} /* 输出:
1: x.c: a
2: x.c: z
*/

方法f()并不是在它的作用域内复制参数Letter y的一个副本,而是传递了一个引用。

3.7 关系操作符

3.7.1 测试对象的等价性

关系操作符==!=也适用于所有对象,看下面这个例子:

public class Equivalence {
    public static void main(Striing[] args) {
        Integer n1 = new Integer(47);
        Integer n2 = new Integer(47);
        System.out.println(n1 == n2);
        System.out.println(n1 != n2);
        }
} /* 输出:
false
true
*/

尽管两个对象的内容相同,但对象的引用却不同。而==!=比较的就是对象的引用。所以输出先是false再是true

要想比较对象实际内容是否相同,可以用特殊方法equals(),它适用于所有对象,但不适用于基本类型。

public class Equivalence {
    public static void main(Striing[] args) {
        Integer n1 = new Integer(47);
        Integer n2 = new Integer(47);
        System.out.println(n1.equals(n2));
        }
} /* 输出:
true
*/

这次结果是相等,但是如果比较的是自己创建的类的对象:

class Value {
    int i;
}

public class EqualsMethod2 {
    public static void main(String[] args) {
        Value v1 = new Value();
        Value v2 = new Value();
        v1.i = v2.i = 100;
        System.out.println(v1.equals(v2));
    }
}  /* 输出:
false
*/

这时结果又变成false了,这是因为equals()默认比较引用,查看equals()方法源码:

public boolean equals(Object obj) {
    return (this == obj);
}

对象都拥有标识(内存地址)和状态(数据),同时“==”比较两个对象的的内存地址,所以说使用Objectequals()方法是比较两个对象的内存地址是否相等,即若object1.equals(object2)true,则表示equals1equals2实际上是引用同一个对象。

3.8 逻辑操作符

与在C和C++中不同的是:Java中不能将一个非布尔值当做布尔值在逻辑表达式中使用:

public clss Bool {
    public static void main(String[] args) {
        Random rand = new Random(47);
        int i = rand.nextInt(100);
        int j = rand.nextInt(100);
        System.out.println("i && j is "+ (i && j));  //非法
        System.out.println("i || j is "+ (i || j));   //非法
        System.out.println("!i is "+ !i);   //非法
    }  
}

所以像while(1)这种写法也是不允许的。

3.9.1 指数计数法

例如:  float expFloat = 1.39e-43f;  “e”也可以大写: float expFloat = 1.39E-43f; 

注意:这里的基数“e”不是自然对数的基数,而表示“10的幂次”,即1.39e-43f的含义是1.39×10-43

对于语句 float f4 = 1e-43f; ,编译器通常会把指数作为double处理,所以要加上这个尾随的f,否则会编译出错,要求把double类型转换成float

3.12 三元操作符

格式:boolean-exp ? value0 : value1

如果boolean-exp(布尔表达式)结果为true就计算value0,结果为false就计算value1,计算结果作为操作符产生的最终的值。

3.13 字符串操作符+和+=

//: operators/StringOperators.java
import static net.mindview.util.Print.*;

public class StringOperators {
  public static void main(String[] args) {
    int x = 0, y = 1, z = 2;
    String s = "x, y, z ";
    print(s + x + y + z);
    print(x + " " + s); // Converts x to a String
    s += "(summed) = "; // Concatenation operator
    print(s + (x + y + z));
    print("" + x); // Shorthand for Integer.toString()
  }
} /* Output:
x, y, z 012
0 x, y, z
x, y, z (summed) = 3
0
*///:~

3.14  使用操作符常见错误

C和C++中写 while(x = y) { //... } ,若y是非零值,结果一定是true,变成死循环。Java会直接抛出错误,除非xy都是布尔值。

Java中要注意区分按位与“&”、按位或“|”和逻辑与“&&”、逻辑或“||”的区别。

3.15 类型转换

1.隐式类型转换

双目运算符组成的表达式,一般要求两边类型一致。若不一致,Java会自动转换为取值范围较大的类型。

2.显式类型转换

隐式类型转换只能“扩展转换”,要想“窄化转换”(即高类型向低类型转换),就必须采用显式类型转换。

注意:布尔型不能类型转换。“类”数据类型也不能类型转换,而是采取特殊方法。

3.15.1 截尾和舍入

执行窄化转换时,必须注意截尾和舍入问题。

floatdouble转型成int型,总是对数字进行截尾。要想得到舍入的结果,就要用java.lang.Math中的round()方法。

转载于:https://www.cnblogs.com/lykxbg/p/10278078.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值