Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么这里使用克隆?_Java_Clone_Vaadin Flow - Fatal编程技术网

Java 为什么这里使用克隆?

Java 为什么这里使用克隆?,java,clone,vaadin-flow,Java,Clone,Vaadin Flow,我正在学习Vaadin教程,偶然发现了这段代码。但是,我无法理解在这种情况下克隆的目的。谁能解释一下吗 /** * Persists or updates customer in the system. Also assigns an identifier for * new Customer instances. * * @param entry */ public synchronized void save(Customer entry) { if (entry == n

我正在学习Vaadin教程,偶然发现了这段代码。但是,我无法理解在这种情况下克隆的目的。谁能解释一下吗

/**
 * Persists or updates customer in the system. Also assigns an identifier for
 * new Customer instances.
 *
 * @param entry
 */
public synchronized void save(Customer entry) {
    if (entry == null) {
        LOGGER.log(Level.SEVERE,
            "Customer is null. Are you sure you have connected your form to the application as described in tutorial chapter 7?");
        return;
    }
    if (entry.getId() == null) {
        entry.setId(nextId++);
    }
    try {
        entry = (Customer) entry.clone();
    } catch (Exception ex) {
        throw new RuntimeException(ex);
    }
    contacts.put(entry.getId(), entry);
}

/**
 * Sample data generation
 */
public void ensureTestData() {
    if (findAll().isEmpty()) {
        final String[] names = new String[] { "Gabrielle Patel", "Brian Robinson", "Eduardo Haugen",
            "Koen Johansen", "Alejandro Macdonald", "Angel Karlsson", "Yahir Gustavsson", "Haiden Svensson",
            "Emily Stewart", "Corinne Davis", "Ryann Davis", "Yurem Jackson", "Kelly Gustavsson",
            "Eileen Walker", "Katelyn Martin", "Israel Carlsson", "Quinn Hansson", "Makena Smith",
            "Danielle Watson", "Leland Harris", "Gunner Karlsen", "Jamar Olsson", "Lara Martin",
            "Ann Andersson", "Remington Andersson", "Rene Carlsson", "Elvis Olsen", "Solomon Olsen",
            "Jaydan Jackson", "Bernard Nilsen" };
        Random r = new Random(0);
        for (String name : names) {
            String[] split = name.split(" ");
            Customer c = new Customer();
            c.setFirstName(split[0]);
            c.setLastName(split[1]);
            c.setStatus(CustomerStatus.values()[r.nextInt(CustomerStatus.values().length)]);
            c.setBirthDate(LocalDate.now().minusDays(r.nextInt(365 * 100)));
            save(c);
        }
    }
}

注意:
Customer
具有以下数据成员:
private Long id,private String firstName=“”,private String lastName=“”,private LocalDate birthDate,private CustomerStatus status,private String email=“”
您的
save
方法是公共的,因此可以从任何地方调用。如果有人保存了一个客户,并在以后更改了他们保存的客户对象,您不希望新的更改反映在您在
联系人中的内容中。在那里保存克隆可以确保您不受克隆操作的影响

但假设save方法不是从
ensureTestData()
以外的任何地方调用的,我们还需要克隆它吗


从技术上讲,这是短期号码。无论您的
方法是保存它创建的客户,还是保存它的克隆,都没有区别。在这种情况下,您需要将
save
方法声明为private,否则您将不知道何时有人从某处引入对它的调用。在许多情况下,人们仍然会进行克隆,以防止将来对代码所做的更改造成不必要的影响。

可能它需要一个对对象的干净引用。我猜测是为了确保对象中的数据在保存期间或之后不会发生更改。在哪种情况下,这是可能的?我想不出有这样的情况。谢谢。@shiva在多个线程处理单个
客户
实例时可能会出现问题,例如Thread1试图保存它。而在
safe
方法中,Thread2可能会改变客户的某些值,并导致不一致性,这会让事情变得明朗起来。但是假设除了
ensuretesta()
之外,没有从任何其他地方调用
save
方法,我们还需要克隆它吗?@shiva问题不在于可以在其他地方调用
ensuretesta()
(无论如何它是同步的),但是传递给该函数的
customer
对象可以同时在其他地方修改。为了确保没有其他线程修改客户实例,您必须克隆它。通过克隆,您可以创建customer类的一个新实例,该实例的值与原始实例的值非常相同,但您可以确保此新克隆未被引用到应用程序中的任何其他地方。