【Java学习】(三)Java中的运算符

时间:2025-04-05 09:53:21

问题1:Java中有哪些运算符?

✅ 在Java中,运算符用于执行各种操作,主要包括算数运算符、关系运算符、逻辑运算符、位运算符、赋值运算符、三元运算符、instanceof运算符等,具体如下:

 1) 算术运算符

  • + 加法
  • - 减法
  • * 乘法
  • / 除法
  • % 取模(取余)
  • ++ 自增
  • -- 自减

示例:

int a = 10;
int b = 3;
int sum = a + b; // 13
int remainder = a % b; // 1
a++; // a 变为 11

2)关系运算符

  • == 等于
  • != 不等于
  • > 大于
  • < 小于
  • >= 大于等于
  • <= 小于等于

示例:

int x = 5;
int y = 10;
boolean result = x > y; // false

3)逻辑运算符

  • && 逻辑与
  • || 逻辑或
  • ! 逻辑非

示例:

boolean a = true;
boolean b = false;
boolean result = a && b; // false

4)位运算符

  • & 位与
  • | 位或
  • ^ 位异或
  • ~ 位非
  • << 左移
  • >> 右移
  • >>> 无符号右移

示例:

int a = 5; // 0101
int b = 3; // 0011
int result = a & b; // 0001 (1)

5)赋值运算符

  • = 赋值
  • += 加后赋值
  • -= 减后赋值
  • *= 乘后赋值
  • /= 除后赋值
  • %= 取模后赋值
  • <<= 左移后赋值
  • >>= 右移后赋值
  • &= 位与后赋值
  • |= 位或后赋值
  • ^= 位异或后赋值

示例:

int a = 10;
a += 5; // a 变为 15

6)条件运算符(三元运算符)

  • ? : 条件运算符

示例:

int a = 10;
int b = 20;
int max = (a > b) ? a : b; // max 为 20

7)instanceof 运算符

  • instanceof 用于检查对象是否为特定类的实例

示例:

String str = "Hello";
boolean result = str instanceof String; // true

8) 其他运算符

  • new 用于创建对象
  • . 用于访问对象的成员
  • [] 用于访问数组元素
  • () 用于方法调用或改变运算顺序

示例:

int[] arr = new int[5];
arr[0] = 10;

问题2:Java中的++i和i++有什么区别?

✅ 在Java中,i++ 和 ++i 都是自增运算符,用于将变量 i 的值增加 1,但它们的行为和使用时机有所不同  ,区别如下:

1)i++(后置自增)

  • 行为:先使用 i 的当前值,然后再将 i 的值增加 1。
  • 特点:先使用,后自增。

示例:

int i = 5;
int result = i++; // result = 5, i = 6
  • 在 result = i++ 中:
  • result 被赋值为 i 的当前值(5)。
  • 然后 i 自增,变为 6。

2) ++i(前置自增)

  • 行为:先将 i 的值增加 1,然后再使用 i 的新值。
  • 特点:先自增,后使用。

示例:

int i = 5;
int result = ++i; // result = 6, i = 6
  • 在 result = ++i 中:
  • i 先自增,变为 6。
  • 然后 result 被赋值为 i 的新值(6)。

3) 区别总结

特性

i++(后置自增)

++i(前置自增)

运算顺序

先使用值,后自增

先自增,后使用值

返回值

返回自增前的值

返回自增后的值

性能

通常与 ++i 性能相同

通常与 i++ 性能相同


问题3:Java运算符在使用时有哪些注意事项?
✅ 在Java中使用运算符时,有一些常见的注意事项和潜在陷阱需要特别留意,以避免程序出现逻辑错误或性能问题。以下是主要的注意事项:
1) 算术运算符
整数除法:两个整数相除时,结果仍然是整数,小数部分会被截断。

int a = 5 / 2; // 结果是 2,不是 2.5

如果需要小数结果,至少一个操作数应为浮点数:

double b = 5.0 / 2; // 结果是 2.5

取模运算符 %:结果的符号与被除数相同。

int c = -5 % 3; // 结果是 -2
int d = 5 % -3; // 结果是 2

溢出问题:在对整数进行运算时,如果结果超出了该整数类型能够表示的范围,就会导致溢出,尤其是 int 和 long 类型。

int max = Integer.MAX_VALUE;
int overflow = max + 1; // 溢出,结果为 Integer.MIN_VALUE

2) 关系运算符
浮点数比较:由于浮点数的精度问题,直接使用 == 或 != 比较浮点数可能导致错误。

double a = 0.1 + 0.2;
if (a == 0.3) { // false,因为 a 的实际值是 0.30000000000000004    
System.out.println("Equal");
}

应使用容差范围(定义一个极小值)进行比较:

double tolerance = 0.00001;
if (Math.abs(a - 0.3) < tolerance) {   
 System.out.println("Equal");
 }

基本类型与引用类型比较:比较基本类型(8种)时,比较的是它们的值。而比较引用类型时,默认比较的是对象的内存地址(除非类重写了 equals方法)。例如:

String s1 = "hello";
String s2 = new String("hello");
System.out.println(s1 == s2); 
System.out.println(s1.equals(s2));

这里 s1 指向字符串常量池中的 "hello",s2 是在堆内存中新建的对象,尽管它们的内容相同,但内存地址不同,所以 == 比较结果为 false。
为了比较引用类型对象的内容,许多类重写了 Object 类的 equals 方法。例如,String 类重写了 equals 方法,用于比较字符串的内容,因此使用equal比较结果相同。
3)逻辑运算符
短路行为:&& 和 || 是短路运算符,如果左侧表达式已经能确定结果,右侧表达式不会执行。

if (false && someMethod()) {    // someMethod() 不会执行}

如果需要强制计算两侧表达式,可以使用 & 或 |。
非短路运算符:& 和 | 会计算两侧表达式,即使左侧已经能确定结果。

if (false & someMethod()) {    // someMethod() 仍然会执行}

4)赋值运算符
复合赋值运算符:如 +=、-= 等,会隐式进行类型转换。

int a = 5;a += 3.5; // a = 8,3.5 被隐式转换为 int

注意类型转换:复合赋值运算符可能导致意外的类型转换。

byte b = 10;b += 128; // 合法,但 b 的值会溢出

5) 条件运算符(三元运算符)
类型一致性:三元运算符的两个结果表达式必须类型一致或兼容。

int a = 5;double b = (a > 0) ? 1.0 : 0; // 合法,0 被提升为 0.0

可读性:避免嵌套过多的三元运算符,否则会降低代码可读性。

int result = (a > 0) ? ((b > 0) ? 1 : 2) : 3; // 不推荐

6)运算符优先级
优先级问题:运算符的优先级可能影响表达式的计算结果。

int result = 5 + 3 * 2; // 结果是 11,不是 16

使用括号明确优先级:

int result = (5 + 3) * 2; // 结果是 16

7)字符串连接运算符 +
类型转换:+ 用于字符串连接时,非字符串操作数会被隐式转换为字符串。

String str = "Value: " + 10; // "Value: 10"

性能问题:在循环中频繁使用 + 连接字符串会导致性能问题,建议使用 StringBuilder。

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100; i++) {    
sb.append(i); 
}
String result = sb.toString();