操作符和赋值
使用操作符
赋值操作符
可以用常量或者表达式的结果来给基本变量赋值。使用了整数 (int
、 short
和 byte
) 的表达式的结果至少为类型 int
。不允许窄化转换,因为它们会导致精度损失。例如:
byte b = 5;
byte c = 4;
byte d = b + c; // does not compile because int cannot fit in a byte
float f = (float)35.67; // implicitly double, so casting to float
float f = 35.67F;
|
只能给布尔变量赋布尔类型的值。
如果我们将现有对象引用赋值给一个引用变量,那么两个引用变量就指向同一个对象。将子对象赋值给父对象是合法的,但是返之则不允许。如果一个对象实现了一个接口,那么您也可以将这个对象引用赋值给这个接口引用变量。例如:
class Base{}
public class Child extends Base
{
public static void main(String argv[])
{
Child child = new Child();
Base base = new Base();
base = child; // Compiles fine
child = base; // Will not compile
}
}
|
instanceof
操作符
instanceof
操作符用于检查一个对象引用是否属于某种类型。这个类型可以是实例或者超类。例如:
class A{}
class B extends A
{
public static void main(String args[])
{
B b = new B();
if(b instanceof A)
System.out.println("b is of type A"); // "b is of type A" is printed
}
}
|
注意,如果一个对象的任何超类实现了特定的接口,那么这个对象就是这种接口类型。
加号 (+)
操作符
加号 (+)
操作符通常用于将两个数相加。如果操作数是 String
对象,那么加号 (+)
操作符就被覆盖以提供连接。例如:
String s1 = "hello ";
String s2 = "World ";
System.out.println(s1 + s2); // prints "hello world"
|
如果一个操作数是 String
,而另一个不是,那么 Java 代码就会试图将另一个操作数转换为 String
表示。如果操作数是一个对象引用,那么就调用其 toString()
方法进行转换:
int i = 10;
String s1 = " rivers";
String s2 = i + s1;
System.out.printlns(s2); // prints "10 rivers"
|
递增和递减操作符
两个快捷的算术操作符是将操作数加 1 的 ++
和将操作数减 --
。
++
递增操作符 (值加 1)
--
递减操作符 (值减 1)
这些操作符可以出现在操作数之前(前缀),也可以出现在操作数之后(后缀)。在前缀的情况下,在递增/递减操作之后对操作数的值进行计算。对于后缀的情况,在递增/递减操作之前对操作数的值进行计算,如下所示:
前缀(操作符放在操作数之前):
int i = 10;
int j = ++i; // j and i are 11
System.out.println(--i); // prints 10
|
后缀(操作符放在操作数之后):
int i = 10;
int j = i++; // j is 10, i becomes 11
System.out.println(i--); // prints 11
|
移位操作符
移位操作符向右或者向左移动数字的位,从而产生新的数字:
>>
右移(用原来符号位的内容填充左面的位)
<<
左移(用零填充右边的位)
>>>
无符号右移(用零填充左边的位)
例如:
8 >> 1;
Before shifting: 0000 0000 0000 0000 0000 0000 0000 1000
After shifting: 0000 0000 0000 0000 0000 0000 0000 0100
|
注意,移动后的位模式相当于十进制的 4。
位操作符
Java 提供了对其操作数进行位操作的四种操作符:
- 如果两个操作数的位都是 1,
&
操作符设置该位为 1。
- 如果只有一个操作数的位是 1,则
^
操作符设置该位为 1。
- 如果至少一个操作数的位为 1,则
|
操作符设置该位为 1。
~
操作符将操作数的每一位的值取反。
例如:
class Test
{
public static void main(String args[])
{
int x = 10 & 9; // 1010 and 1001
System.out.println(x);
} // prints 8, which is the decimal equivalent of 1000
}
|
位操作符 &
和 |
也可以用于布尔表达式。
逻辑操作符
四种逻辑操作符是 &
、 &&
、 |
和 ||
。
如果两个操作数都为 true,那么 &
和 &&
操作符返回 true
。
如果至少有一个操作数为 true,那么 |
和 ||
操作符返回 true
。
&
和 |
操作符总是判断两个操作数。 &&
和 ||
称为 short circuit 操作符,因为如果左边的操作数就可以确定布尔表达式的结果,那么它们就不对右边的操作数进行判断了。例如:
if ((++x > 2) || (++y > 2)) { x++; }
// y is incremented only if (++x > 2) is false
|
注意 ||
和 &&
只能用于逻辑表达式。
回页首
equals() 方法
我们可以用 ==
操作符来比较基本类型变量的值并确定它们是否相等。不过,如果用 ==
操作符比较对象引用变量,那么如果引用变量指向同一个对象时它返回 ture
。为了检查两个对象的相等性, Object
类提供了 equals(Object obj)
方法,可以覆盖它以对逻辑相等的对象返回 true
。 Object
类的 equals()
方法的默认实现只有当对象与它自己比较时才返回 true
-- 也就是说,它的行为类似于 ==
操作符。像 String
和 Boolean
这样的类覆盖了 equals()
方法,而 StringBuffer
则没有。例如:
String s1 = "abc";
String s2 = new String("abc");
if (s1 == s2) // returns false
System.out.println("Same Object Reference");
if (s1.equals(s2)) // returns true
System.out.println("Equal Objects"); // prints "Equal Objects"
|
回页首
将变量传递给方法
如果传递的变量是基本类型,那么实际上只是变量的副本传递给了方法。所以在方法中修改变量不会影响实际的变量。
将对象变量传递给方法时,实际传递的是引用变量的副本。在这里,两个变量指向的是同一个对象。如果在方法里面修改对象,那么在原来的变量里也可以看到变化。尽管调用的方法可以改变由传递的变量引用的对象,但是它不能在改变调用方法中改变实际的变量。换句话说,不能对原始引用变量重新赋予其他的值。例如:
class MyClass
{
int a = 3;
void setNum(int a)
{
this.a = a;
}
int getNum()
{
return a;
}
}
class Test
{
static void change(MyClass x)
{
x.setNum(9);
}
public static void main(String args[])
{
MyClass my = new MyClass();
change(my);
System.out.println(my.getNum()); // Prints 9
}
}
|
在上面的例子中,可以看到改变 x 引用的对象也改变了由 my
引用的同一个对象。
回页首
小结
本节我们讨论了不同的操作符和赋值规则。您应该理解按位操作符 (&
和 |
) 和逻辑操作符 (& &
和 ||
)的区别。要清楚用 ==
操作符进行的是什么样的相等性比较,以及 equals()
方法对于对象的意义。同时,要记住对象是用引用值的副本传递的,而基本类型是用基本类型的值的副本传递的。
回页首
练习
问题:
编译和运行下面这段代码的结果是什么?
Integer i= new Integer("10");
if (i.toString() == i.toString())
System.out.println("Equal");
else
System.out.println("Not Equal");
|
选项:
- A. 编译错误
- B. 输出“Equal”
- C. 输出“Not Equal”
- D. 以上都不是
正确答案:
说明:
toString()
方法返回等同于这个 String
对象的 String
。它每次调用时创建一个新的对象。 ==
操作符比较两个对象引用的位模式而不是实际的 String
内容。因此比较返回 false
,执行 else
语句,输出“Not Equal”。