Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are there new arguments to use getters and setters since Java 8?

As the title says, there has always been quite a discussion about getters and setters in any programming language, so also Java.

The question is the following: Are there any new arguments since Java 8 got released?

An example of an already existing argument is that getters and setters encapsulate state, or that they make it possible to change the implementation without changing the API.

like image 613
skiwi Avatar asked Mar 25 '14 13:03

skiwi


People also ask

Is it a good practice to use getters and setters?

In Java you should use getters and setters : It's considered a good practice because it encapsulates your object's inner state, therefore you can change the internals of the object and change the meaning of the value, doing complex things with it without changing its interface.

Do you need getters and setters in Java?

Introduction. Getters and Setters play an important role in retrieving and updating the value of a variable outside the encapsulating class. A setter updates the value of a variable, while a getter reads the value of a variable.

Why are there no getters and setters?

Getter and setter methods (also known as accessors) are dangerous for the same reason that public fields are dangerous: They provide external access to implementation details. What if you need to change the accessed field's type? You also have to change the accessor's return type.

Should classes always have getters and setters?

The usual rule for these kinds of classes is to make fields private and provide get and set methods because once you make something public and some other class depends on it you can't change it.


1 Answers

Yes, there are! Since Java 8 method references were introduced, and as their name says, they can only be used with methods.

Consider the following code:

class Person {
    private String firstName;
    private String lastName;

    public Person(final String firstName, final String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return firstName + " " + lastName;
    }
}

Assume we want to obtain a map that contains a lists of people grouped by their last name, we can only do that via method references with the following code:

List<Person> personList = new ArrayList<>();
personList.add(new Person("Shannon", "Goldstein"));
personList.add(new Person("Donnie", "Denney"));
personList.add(new Person("Mark", "Thomas"));
personList.add(new Person("Julia", "Thomas"));
Map<String, List<Person>> personMapping = personList.stream()
        .collect(Collectors.groupingBy(Person::getLastName));
System.out.println("personMapping = " + personMapping);

Which prints out, formatted nicely:

personMapping = {
    Thomas=[Mark Thomas, Julia Thomas], 
    Goldstein=[Shannon Goldstein], 
    Denney=[Donnie Denney]
}

This would not have worked if we were using public variables, as you cannot obtain a method reference on them, nor reference them in another way other than writing a full-fledged lambda where it is not neccessary.
(For curious people: person -> person.lastName would need to have been used)

Also, keep in mind that this answer differs from someone claiming that if an object needs to adhere to a certain interface, that then getters and setters must be used. As in this example the Person class adheres to no interface, yet benefits from having getters available.

like image 150
skiwi Avatar answered Nov 08 '22 18:11

skiwi