Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

This question already has an answer here:

In school, I've been told many times to stop using public for my variables. I haven't asked why yet.

This question: Are Java's public fields just a tragic historical design flaw at this point? seems kinda related to this. However, they don't seem to discuss why is it "wrong", but instead focus on how can they use them instead.

Look at this (unfinished) class:

public class Reporte {

    public String rutaOriginal;
    public String rutaNueva;
    public int bytesOriginales;
    public int bytesFinales;
    public float ganancia;

    /**
     * Constructor para objetos de la clase Reporte
     */
    public Reporte() {

    }
}

No need to understand Spanish. All this class does is hold some statistics (those public fields) and then do some operations with them (later).

I will also need to be modifying those variables often. But well, since I've been told not to use public, this is what I ended up doing:

public class Reporte {

    private String rutaOriginal;
    private String rutaNueva;
    private int bytesOriginales;
    private int bytesFinales;
    private float ganancia;

    /**
     * Constructor para objetos de la clase Reporte
     */
    public Reporte() {

    }

    public String getRutaOriginal() {
        return rutaOriginal;
    }

    public String getRutaNueva() {
        return rutaNueva;
    }

    public int getBytesOriginales() {
        return bytesOriginales;
    }

    public int getBytesFinales() {
        return bytesFinales;
    }

    public float getGanancia() {
        return ganancia;
    }

    public void setRutaOriginal(String rutaOriginal) {
        this.rutaOriginal = rutaOriginal;
    }

    public void setRutaNueva(String rutaNueva) {
        this.rutaNueva = rutaNueva;
    }

    public void setBytesOriginales(int bytesOriginales) {
        this.bytesOriginales = bytesOriginales;
    }

    public void setBytesFinales(int bytesFinales) {
        this.bytesFinales = bytesFinales;
    }

    public void setGanancia(float ganancia) {
        this.ganancia = ganancia;
    }
}

Looks kinda pretty. But seems like a waste of time.

Google searches about "When to use public in Java" and "Why shouldn't I use public in Java" seem to discuss about a concept of mutability, although I'm not really sure how to interpret such discussions. I do want my class to be mutable - all the time.

share|improve this question
    
programmers.stackexchange.com/a/170972/42031 is my answer to a similar question which explains the reasons for not using public in Java. –  Deco Nov 23 '12 at 3:27
1  
Think about what would you need to do if you liked to ensure that "rutaOriginal" is never set to null. Can you do that with a public member variable? And how about that "ganancia" -- doesn't it need to be recalculated after bytesOriginal or bytesFinales changes? With public members your object would not get notified of such changes. –  COME FROM Nov 23 '12 at 9:36
add comment

marked as duplicate by Jim G., GlenH7, gnat, Kilian Foth, MichaelT Oct 22 '13 at 15:15

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

2 Answers

up vote 11 down vote accepted

It breaks encapsulation - the core principle here is that the fields of your class are implementation details, by exposing it as a public field, you are telling everything outside that class that it is an actual piece of data that is stored by the class - something external classes don't need to know, they just need to be able to get or set that piece of data. As soon as you make something public, external classes should be able to depend on it, and it should not change often, by implementing as a method, you are retaining the flexibility to change the implementation at a later point without affecting users of the class.

If you wanted to change one of the fields so it's calculated, or retrieved from a service when its called, you wouldn't be able to without breaking other parts of your application. Other reasons are that it allows you to control access to the variable (i.e. make it immutable as you already highlighted). In setters you can also add checking code, and you can add behaviors to getters and setters that do other things when a variable is get or set (though this may not always be a good thing). You can also override a method in a derived class, you can't override a field.

There are some very rare situations where it is better to have public field instead of a method - but this really only applies in very high performance applications (3D games & financial trading applications), unless you are writing one of these, avoid public fields - and if you do care about performance to that level, Java is probably not the best choice anyway.

Just a note on mutability - in general you should try to make things immutable until you have a genuine reason to make them mutable - the less your code exposes in its public API, the easier it is for long term maintenance, and in a multi-threaded situation, immutable objects are threadsafe, mutable objects need to implement locking.

share|improve this answer
    
So I do have to make those methods up there (normally)? –  Omega Nov 23 '12 at 1:49
    
@Omega Encapsulation is one of the basic principles of OOP. It's advantages have been proven for decades. If your class is immutable you don't write the setters. This answer explains it very well. Most IDEs will create the getters and setters for you so you don't have to. –  user61852 Nov 23 '12 at 2:07
    
Can you provide some examples of why a public field instead of a method would make any difference in a 3D game or financial trading application –  Deco Nov 23 '12 at 3:25
1  
When you invoke a method the address of the method must be looked up first - which takes a very small amount of time. In most apps this additional overhead is negligible, but in a financial trading application (e.g. algorithmic trading) price calculations must be done in sub-ms time to be able to compete with the rest of the market. In 3D games, every frame of the game requires a large number of calcs, because there are so many operations, done at up to 60 times/s, the overhead can be significant. That said - these apps usually use C/C++ as without memory management it performs far better. –  Brian Flynn Nov 23 '12 at 3:47
1  
The VM can inline method calls that are used frequently. In fact, there's generally little-to-no overhead when it matters. Hotspot and the later versions of the JVM (1.6+) have become very good at doing this. –  Deco Nov 23 '12 at 6:18
show 4 more comments

Encapsulation is one of the four fundamental OOP concepts. The other three are inheritance, polymorphism, and abstraction.

Encapsulation is the technique of making the fields in a class private and providing access to the fields via public methods. If a field is declared private, it cannot be accessed by anyone outside the class, thereby hiding the fields within the class. For this reason, encapsulation is also referred to as data hiding.

Encapsulation can be described as a protective barrier that prevents the code and data being randomly accessed by other code defined outside the class. Access to the data and code is tightly controlled by an interface.

The main benefit of encapsulation is the ability to modify our implemented code without breaking the code of others who use our code. With this feature Encapsulation gives maintainability, flexibility and extensibility to our code. Benefits of Encapsulation:

The fields of a class can be made read-only or write-only.

A class can have total control over what is stored in its fields.

The users of a class do not know how the class stores its data. A class can change the data type of a field, and users of the class do not need to change any of their code.he public methods are the access points to this class's fields from the outside java world. Normally these methods are referred as getters and setters. Therefore any class that wants to access the variables should access them through these getters and setters.

share|improve this answer
add comment

Not the answer you're looking for? Browse other questions tagged or ask your own question.