运算

2023/11/6 Java基础

# 1、参数传递

Java 的参数是以值传递的形式传入方法中,而不是引用传递。 基本类型直接传值,引用类型传递对象的地址值,也是值传递。

以下代码中 Dog dog 的 dog 是一个指针,存储的是对象的地址。在将一个参数传入一个方法时,本质上是将对象的地址以值的方式传递到形参中。

public class Dog {

    String name;

    Dog(String name) {
        this.name = name;
    }

    String getName() {
        return this.name;
    }

    void setName(String name) {
        this.name = name;
    }

    String getObjectAddress() {
        return super.toString();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

在方法中改变对象的字段值会改变原对象该字段值,因为引用的是同一个对象。

class PassByValueExample {
    public static void main(String[] args) {
        Dog dog = new Dog("A");
        func(dog);
        System.out.println(dog.getName());          // B
    }

    private static void func(Dog dog) {
        dog.setName("B");
    }
}
1
2
3
4
5
6
7
8
9
10
11

但是在方法中将指针引用了其它对象,那么此时方法里和方法外的两个指针指向了不同的对象,在一个指针改变其所指向对象的内容对另一个指针所指向的对象没有影响。

public class PassByValueExample {
    public static void main(String[] args) {
        Dog dog = new Dog("A");
        System.out.println(dog.getObjectAddress()); // Dog@4554617c
        func(dog);
        System.out.println(dog.getObjectAddress()); // Dog@4554617c
        System.out.println(dog.getName());          // A
    }

    private static void func(Dog dog) {
        System.out.println(dog.getObjectAddress()); // Dog@4554617c
        dog = new Dog("B");
        System.out.println(dog.getObjectAddress()); // Dog@74a14482
        System.out.println(dog.getName());          // B
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

参考:StackOverflow: Is Java “pass-by-reference” or “pass-by-value”? (opens new window)

# 2、float与double

1.1 字面量属于 double 类型,不能直接将 1.1 直接赋值给 float 变量,因为这是向下转型。Java 不能隐式执行向下转型,因为这会使得精度降低。

// float f = 1.1;

double d = 1.1;
// 或者 double d = 1.1d;
1
2
3
4

1.1f 字面量才是 float 类型。

float f = 1.1f;
1

double 不能向下转型为 float,但是float 可以向上转型为 double。

# 3、类型转换

类型转换分为强制类型转换隐式类型转换

  • 隐式类型转换

因为字面量 1 是 int 类型,它比 short 类型精度要高,因此不能隐式地将 int 类型向下转型为 short 类型。

short s1 = 1;
// s1 = s1 + 1;
1
2

解释一下

s1定义为short类型,s1+1的1是int类型,s1是short类型,运算结果为int类型(以后面高精度的为准,毕竟short装不下int类型),int类型不能直接赋值给short类型,所以报错。

但是使用 += 或者 ++ 运算符会执行隐式类型转换。

s1 += 1;
s1++;
1
2

上面的语句相当于将 s1 + 1 的计算结果进行了向下转型:

s1 = (short) (s1 + 1);
1
  • 强制类型转换

强制类型转换是指将一个数据类型强制转换为另一个数据类型。强制类型转换可能会丢失信息,例如将浮点数强制转换为整数时,小数部分将被丢弃。

double myDouble = 9.78;
int myInt = (int) myDouble; // this will be 9
1
2

像隐式类型转换中的将int转为short也是强制类型转换。

s1 = (short) (s1 + 1);
1

参考:StackOverflow : Why don't Java's +=, -=, *=, /= compound assignment operators require casting? (opens new window)

# 4、switch

从 Java 7 开始,可以在 switch 条件判断语句中使用 String 对象。

String s = "a"; 
switch (s) {
    case "a":
        System.out.println("aaa");
        break;
    case "b":
        System.out.println("bbb");
        break;
}
1
2
3
4
5
6
7
8
9

switch 不支持 long、float、double,是因为 switch 的设计初衷是对那些只有少数几个值的类型进行等值判断,如果值过于复杂,那么还是用 if 比较合适。

// long x = 111;
// switch (x) { // Incompatible types. Found: 'long', required: 'char, byte, short, int, Character, Byte, Short, Integer, String, or an enum'
//     case 111:
//         System.out.println(111);
//         break;
//     case 222:
//         System.out.println(222);
//         break;
// }
1
2
3
4
5
6
7
8
9

参考:StackOverflow : Why can't your switch statement data type be long, Java? (opens new window)