Search code examples
javaclonevaadin-flow

Why is clone used here?


I was going through a Vaadin tutorial and came across this piece of code. However I can't understand the purpose of clone in this scenario. Can anyone please explain?

/**
 * 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);
        }
    }
}

Note: Customer has the following data members: private Long id, private String firstName = "", private String lastName = "", private LocalDate birthDate, private CustomerStatus status, private String email = ""


Solution

  • Your save method is public so can be called from anywhere. If someone saves a customer and later alters the customer object they have saved, you don’t want the new changes reflected in what you’ve got in contacts. Saving a clone there ensures that you are not affected by what they are doing.

    But assuming save method isn't called from anywhere else other than ensureTestData(), do we still need to clone it?

    Technically on the short sight no. Whether your ensureTestData method saves the customer it has created or a clone of it makes no difference. In that case you would need to declare the save method private, though, or you won’t know when someone is introducing a call to it from somewhere. In many cases one would still clone to prevent future changes to the code from causing unwanted effects.