MST

星途 面试题库

面试题:Java 引用传递在复杂对象结构方法调用中的影响

假设有一个包含多个嵌套对象的复杂数据结构,例如一个公司类,公司类包含部门列表,部门类又包含员工列表。在对这样的复杂对象结构进行方法调用时,引用传递可能会带来哪些问题,如何避免这些问题?请结合代码示例进行说明。
33.2万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

引用传递可能带来的问题

  1. 数据意外修改:当通过引用传递对象时,被调用方法可能会意外修改对象的状态,这会影响到调用者的业务逻辑。例如,在公司 - 部门 - 员工的结构中,如果一个方法本意只是读取员工信息,但不小心修改了员工的工资等信息,这可能导致调用者的业务出现错误。
  2. 内存共享问题:多个引用指向同一对象,可能导致内存管理上的困惑。比如当一个对象应该被销毁,但由于其他地方还持有其引用,导致对象无法正常释放内存。

避免这些问题的方法

  1. 使用不可变对象:将对象设计为不可变,一旦创建,其状态就不能被修改。例如,员工类中的属性可以在构造函数中初始化,并且不提供修改属性的方法。
  2. 深度拷贝:在传递对象前,对对象进行深度拷贝,这样被调用方法操作的是拷贝后的对象,不会影响原始对象。

代码示例

import java.util.ArrayList;
import java.util.List;

// 员工类
class Employee {
    private String name;
    private int salary;

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

    // 这里不提供修改 salary 的方法,保证不可变
    public String getName() {
        return name;
    }

    public int getSalary() {
        return salary;
    }
}

// 部门类
class Department {
    private String departmentName;
    private List<Employee> employees;

    public Department(String departmentName) {
        this.departmentName = departmentName;
        this.employees = new ArrayList<>();
    }

    public void addEmployee(Employee employee) {
        employees.add(employee);
    }

    public List<Employee> getEmployees() {
        // 返回不可变的拷贝
        return List.copyOf(employees);
    }
}

// 公司类
class Company {
    private String companyName;
    private List<Department> departments;

    public Company(String companyName) {
        this.companyName = companyName;
        this.departments = new ArrayList<>();
    }

    public void addDepartment(Department department) {
        departments.add(department);
    }

    public List<Department> getDepartments() {
        // 返回不可变的拷贝
        List<Department> copy = new ArrayList<>();
        for (Department department : departments) {
            Department copiedDepartment = new Department(department.departmentName);
            for (Employee employee : department.getEmployees()) {
                copiedDepartment.addEmployee(new Employee(employee.getName(), employee.getSalary()));
            }
            copy.add(copiedDepartment);
        }
        return copy;
    }
}

public class Main {
    public static void main(String[] args) {
        Company company = new Company("示例公司");

        Department department = new Department("技术部");
        department.addEmployee(new Employee("张三", 5000));
        company.addDepartment(department);

        List<Department> departments = company.getDepartments();
        // 这里获取的 departments 是拷贝后的,对其修改不会影响原始的 company 对象
    }
}

在上述代码中,Employee类设计为不可变,Department类和Company类通过返回不可变的拷贝(List.copyOf或手动深度拷贝)来避免引用传递带来的问题。