我们已经学会了如何定义和初始化变量,然而程序中的数据并不是一成不变的,很多时候我们需要对数据进行“操作”。
运算符是Java语言中一种直观的数据操作方式,它可以对特定的一个或者多个变量进行运算并返回结果。
大部分运算符可以接受基本类型作为操作数。
部分操作符如'=
'、'==
'、'!=
',可以操作任意对象,即支持引用类型。
与大部分编程语言相同,Java使用'=
'运算符来进行赋值操作。这种操作会将右边的计算结果(称为右值)赋给左边的变量。
右值可以为任意常数、变量或表达式而左值必须为一个明确的变量。如:
下面的表达式是不能编译通过的:
因为我们不能将任何东西赋给常数。
在Java中,使用'=
'对一个对象进行赋值时,真正操作的是它的引用,即是对对应的引用进行拷贝。这也正是上一节内容中引用类型的含义。
比如:
接下来我们来了解一下都有哪些算数运算符,讲解过程中会涉及到一些简单的代码。我们可以将这些代码拷贝HelloWorld
类的main
函数中执行来查看效果。
注意一个方法内的变量名是不能重复的,查看某个变量的值,将其传入System.out.println()
方法中即可。
Java提供了包括加减乘除、取模在内的算数运算符。
以加法运算为例,如果我们要将x
变量的值增加4,可以这样写:
Java提供了同时进行算数运算和赋值的运算符,可以这样写:
这一行代码与上一行代码是等价的。
其他算数运算符'*
', '/
', '-
', '%
',对应的赋值运算符分别为'*=
','/=
','-=
','%=
'。
Java也提供了自增自减运算符'--
'和'++
'来使编码更为简洁,它们分别表示增加1
和减少1
:
上面的代码中,前三行代码完全等价,后三行代码也完全等价。
数学运算中存在自动类型转换:
byte
、short
与char
进行数学运算,会自动转换为int
关系运算符生成布尔(boolean
)类型的结果,即返回true
或者false
。
关系操作符包括:
关系运算符 | 关系 |
---|---|
> |
大于 |
< |
小于 |
== |
等于 |
!= |
不等于 |
>= |
大于等于 |
<= |
小于等于 |
'==
'和'!=
'适用于所有类型的值和对象(即基本类型变量和引用类型变量)。
'>
'、'<
'、'>=
'和'<=
'不适用于布尔类型的值,因为它们只有true
或false
,大于和小于并无实际意义。
提高
'==
'和'!=
'作为关系运算符只用来比较对象的引用。
如果想比较两个对象实际内容是否相同,需要调用对象的equals()
方法。比如判断一个字符串str
的内容是否为"abcd",应该这样比较:
下面这种方式是一种错误的方式:
逻辑运算符的结果和操作的对象均为布尔值。
逻辑操作符包括:
逻辑运算符 | 逻辑关系 |
---|---|
&& |
与 |
|| |
或 |
! |
非 |
比如说我们要通过编程计算y = |x * (x - 1)|
这个表达式的值,我们即可使用逻辑运算符进行运算:
在Java中,逻辑运算符支持短路操作,一旦能够明确表达整个表达式的值,我们就不需要计算表达式的余下部分了。比如我们需要判断一个对象不为空且它的某个方法返回值不为空,我们就可以这样判断:
如果object
为空,第一部分表达式object != null
会返回false
,那么不管&&
运算符后面的表达式object.someFunction() != null
的结果如何,最终的值都为false。编译器会自动将这部分运算进行优化,不会执行object.someFunction() != null
。
位运算符面向的运算对象是二进制的“位”,可应用于整数类型(int),长整型(long),短整型(short),字符型(char),和字节型(byte)等类型,运算时会将其对应Bit位(0或者是1)进行布尔代数运算或者移动操作。
位运算符 | 计算逻辑 |
---|---|
& |
与运算:对于某一位,只要两个操作数都为1,则该位的结果为1,否则为0 |
| |
或运算:对于某一位,只要两个操作数有一个为1,则该位的结果为1,否则为0 |
^ |
异或运算:对于某一位,如果两个操作数不相同,则该位的结果为1,否则为0 |
~ |
非运算:按位补运算符翻转操作数的每一位 |
<< |
二进制左移运算符:左操作数按位左移右操作数指定的位数 |
>> |
二进制右移运算符:左操作数按位右移右操作数指定的位数 |
>>> |
二进制右移补零操作符:左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充 |
计算逻辑的描述读起来有些晦涩,我们通过例子可以更清晰得了解位运算符如何进行计算。假设如果x
等于60;y
等于13;则它们的二进制表示,以及位运算的结果如下所示:
x = 0011 1100
y = 0000 1101
-----------------
x & y = 0000 1100
x | y = 0011 1101
x ^ y = 0011 0001
~x = 1100 0011
x << 2 = 1111 0000
x >> 2 = 0000 1111
x >>> 2 = 0000 1111
注意>>
和>>>
的区别:
>>
,若操作的值为正,则在高位插入0;若值为负,则在高位插入1;>>>
,无论正负,都在高位插入0。Java中的条件运算符是一个三元运算符,它的形式如下:
如果布尔表达式值为true,则表达式的值为valueWhenTrue
的值,否则为valueWhenFalse
的值。
比如我们要计算x
的绝对值,可以通过如下代码实现:
通过三元运算符,只需要一条语句y = x >= 0 ? x : -x;
就可以完成,更为简洁。
我们在很多情况下会用到类型转换。在适当的时候,Java也会根据数据类型将数据类型自动转为另一种。比如我们为float
变量赋一个整数值,编译器会将int
转化为float
赋给变量。
但是在很多情况下,Java并不能判断我们是否需要进行类型转换,这时就需要类型转化运算符,它允许我们显式地进行类型转换,如:
我们对变量和常量都能进行类型转换。
在对浮点数进行类型转换时,我们需要注意截尾的问题。如我们要将10.9进行类型转换:(int) 10.9
,它的值并不是四舍五入的11,而是10。
运算符优先级决定一个表达式里术语的分组。它影响着一个表达式如何求值。一定的运算符比其他运算符拥有更高的优先级。
例如:乘法运算符比加法运算符有更高的优先级,表达式1 + 5 * 6
,根据运算符的优先级,编译器会先计算5 * 6
,再计算30 + 1
,最终得到结果31
。
各类各运算符的优先级从大到小如下:
.
, ()
, []
单目+
(右到左结合), 单目-
(右到左结合), ++
, --
, ~
, !
*
, /
,%
+
(左到右结合), -
(左到右结合)
>>
, <<
, >>>
<
, <=
, >
, >=
==
, !=
&
|
^
&&
||
?:
=
, +=
等赋值运算符
不用担心这么复杂的优先级列表,绝大多数情况下,表达式本身就很容易看得出优先级,比如赋值运算肯定是优先级最低的。在对优先级不太明确的情况下,我们使用括号就能按照我们希望的方式来改变优先级,所以不需要对运算符优先级做太多记忆。
登录发表评论 登录 注册
高位是什么 ,是指从左到右 例如 0000 1111的第一个0吗?
a的平方a^2中的 “^” 与位异或运算符“^” 是一样的嘛?
参考下面的代码,可以理解equals()和== 的区别:前者是比较是值相等,后者是比较地址相等。
下面这种方式是一种错误的方式:
if (str == "abcd") { }
============
以上语句我测试怎么这个也是正确的呢?
可以这么认为
“==”作为关系运算符只用来比较对象的引用 即是 比较对象的地址吗?
为什么不同类型的数据进行运算,会自动转换为“更高级别”的类型
以int移位为例,移n位的话,如果n < 0, 会移动 n % 32 + 32 位。
你好,我想请问一下这里的右移运算符中说明的“操作的值的正负性”问题。请问一下这个操作的值具体指的是x >> 2中的这个2吗?就是说可以有x>> -2的表达方式??
那么这种情况下 blog 和 blogB 可以使用 euqals() 方法来比较吗?如果可以的话,比较的是什么?
返回为true,因为它们指向同一个对象。
'
==
'和'!=
'适用于所有类型的对象。'>'、'<'、'
>=
'和'<=
'不适用于布尔类型的值,因为它们只有true
或false
,大于和小于并无实际意义。'
==
'和'!=
'适用于所有类型的对象,其他关系运算符并不适用于布尔类型的值,因为它们只有true
或false
,大于和小于并无实际意义。请问上述这句话应该怎么理解?
作业里面第二问,我按照你们的预设不会写,但是改了一下也通过了,我想知道,你们预设想我怎么写?
public boolean operation(int a, int b) {
boolean fals;
fals=((a&b)>(a|b))?true:false
return fals;
}
跟赋值类似,一个是先打印后自增,一个是先自增后打印
public class LianXi {
public static void main(String[] args) {
// TODO Auto-generated method stub
int a=5;
int b=5;
System.out.println("使用后置运算符得结果为:"+(a++));//显示后置结果
System.out.println("使用前置运算符得结果为:"+(++b));//显示前置结果
int a1=5;
a1++;
System.out.println(a1);
}
} 有点不太理解为什么 运行输出得a是5,b是6。.
涉及到赋值的时候,语义不一样。一个是新自增再赋值,一个是先赋值再自增。不涉及赋值的时候,语义是一样的。
在运算的时候我发现比如 int a = 5;
++a;与a++;得到的数据是一样的。可以这么理解吗?还是习惯上自增自减在后面更好一些。谢谢啦
基础知识的话,学习Java的基本概念和语法之后,然后动手练习吧,重在练习。
快速学习JAVA 的基础知识,有什么好的方法和建议吗?请指教!!!!!
或运算写错了 \ | --> ||