【Java】核心技术 卷Ⅰ阅读笔记

P63 块作用域

在C++中可以在嵌套的块中重新定义一个变量,在内层定义的变量会覆盖外层定义的变量,但在java中不允许这样做

public static void main(String[] args) {
        int n = 10;
        {
            int k = 10;

            /**
             * 错误提示:Variable 'n' is already defined in the scope
             * 在C++中可以在嵌套的块中重新定义一个变量,在内层定义的变量会覆盖外层定义的变量,
             * 但在java中不允许这样做
             */
            int n = 20;
        }
    }
P63 & P127 块作用域 & 默认字段初始化

数组会给数组中的元素初始化;类的属性也会在调用构造方法时被初始化;但方法中的局部变量不会被初始化,所以必须明确初始化。

整型初始化为0,浮点型初始化为0.0,String类型初始化为null,boolean类型初始化为false类型

public class Test {
    public static void main(String[] args) {
        /**
         * 运行结果:[null, null, null, null, null]
         * 数组中的元素会被初始化
         */
        String[] arr = new String[5];
        System.out.println(Arrays.toString(arr));

        /**
         * 运行结果:name = null  age = 0
         * 对象中的属性也会被初始化
         */
        Person person = new Person();
        System.out.println("name = " + person.name);
        System.out.println("age = " + person.age);

        /**
         * 编译出错
         */
        int i;
        System.out.println(i);
    }
}

class Person{
    public String name;
    public int age;
}
P121 ~ P123 方法参数

java中有2种类型的方法参数

  • 基本数据类型(数字、布尔)
  • 对象引用

对于基本数据类型,一个方法不可能修改基本数据类型的值,但对于对象引用,方法引用得到的是对象引用的副本,原来的对象引用和副本都引用同一个对象,所以通过副本引用能够修改对象的属性。但是需要注意的是,只能通过副本引用修改对象的值,如果想要通过副本引用修改原来对象引用的值,是不会成功的。

// 程序清单4-4
public class Test {
    public static void main(String[] args) {
        /**
         * 方法参数为 基本数据类型
         * 声明一个变量percent,调用tripleValue()方法
         * 但由于是按值调用,所以在方法调用完毕后,percent的值仍然为10
         */
        System.out.println("Testing tripleValue:");
        double percent = 10;
        System.out.println("Before: percent = " + percent);
        tripleValue(percent);
        System.out.println("After: percent = " + percent);

        /**
         * 方法参数为 对象引用
         * 创建一个对象的副本变量,这个副本变量也指向对象本身的地址
         * 所以当通过副本变量修改对象本身的值时,对象的值发生改变
         */
        System.out.println("\nTesting tripleSalary");
        var harry = new Employee("Harry", 50000);
        System.out.println("Before: salary = " + harry.getSalary());
        tripleSalary(harry);
        System.out.println("After: salary = " + harry.getSalary());

        /**
         * 方法参数为 按值传递
         * 这里的swap()方法把Alice和Bob变量的地址传递给x和y
         * 通过x和y能够修改Alice和Bob中变量的值,但是如果在swap()方法中交换两个对象
         * 那么x存放的是Bob变量,而y存放的是Alice对象
         * 但在方法结束时,变量Alice和Bob仍然指向原来的对象,并没有发生交换
         */
        System.out.println("\nTesting swap:");
        var Alice = new Employee("Alice", 70000);
        var Bob = new Employee("Bob", 60000);
        System.out.println("Before: Alice = " + Alice.getSalary());
        System.out.println("Before: Bob = " + Bob.getSalary());
        tripleSalary(Alice);
        tripleSalary(Bob);
        swap(Alice, Bob);
        System.out.println("After: Alice = " + Alice.getSalary());
        System.out.println("After: Bob = " + Bob.getSalary());
    }

    public static void tripleValue(double x){
        x *= 3;
    }

    public static void tripleSalary(Employee x){
        x.raiseSalary(200);
        System.out.println("End of method: salary = " + x.getSalary());
    }

    public static  void swap(Employee x, Employee y){
        Employee temp = x;
        x = y;
        y = temp;
        System.out.println("End of method x = " + x.getName());
        System.out.println("End if method y = " + y.getName());
    }
}

class Employee{
    private String name;
    private double salary;

    public Employee(String name, double salary){
        this.name = name;
        this.salary = salary;
    }

    public String getName() {
        return name;
    }

    public double getSalary() {
        return salary;
    }

    public void raiseSalary(double ByPercent){
        double raise = salary * ByPercent / 100;
        salary += raise;
    }
}
P130 ~ P133 初始化块和静态代码块

初始化代码块的③种方法:

  1. 在声明中赋值
  2. 在构造器中设置值
  3. 在初始化块中赋值

初始化块(构造类时调用):在一个类的声明中,可以包含任意多个代码块。只要构造这个类的对象,这些块就会被执行。但是,通常会将初始化块放在构造器中。

静态代码块(加载类时调用):随着类的加载而执行,而且只执行一次。也就是说这些代码不需要实例化类就能够被调用。一般情况下,如果有些代码必须在项目启动的时候就执行,就需要使用静态代码块。

import java.util.Random;

public class Test {
    public static void main(String[] args) {
        var staff = new Employee[3];

        staff[0] = new Employee("Harry", 40000);
        staff[1] = new Employee(60000);
        staff[2] = new Employee();

        for (Employee e : staff){
            System.out.println(e);
        }
    }
}

class Employee{
    private static int nextId;
    private int id;
    private String name = "";
    private double salary;

    // 静态代码块:用于初始化静态变量
    static{
        var generator = new Random();
        nextId = generator.nextInt(10000);
    }

    // 初始化块
    {
        id = nextId;
        nextId++;
    }

    public Employee() {}

    public Employee(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }

    public Employee(double salary){
        this("Employee #" + nextId, salary);
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public double getSalary() {
        return salary;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", salary=" + salary +
                '}';
    }
}
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页