views:

771

answers:

27

I have a data class in my application. My application will never be used as a public API and I will be the only person developing code within my project.

I am trying to save every ounce of processor and memory power I can.

Is it a bad idea to make my data members in my data class to have public/protected/default protection so that I don't have to use a getter? Using a getter would require slightly more memory and creation of a stack and such...which I believe isn't necessary. The only reason I can see in using a getter is for protection/privacy, but if I'm the only coder and nobody else is going to be using my API, then is it a bad idea not to use the getters?

Please let me know if this is stupid.

+2  A: 

This is slightly heretical, but I agree with you that if you know nobody else is going to be using your class, you can skip that stuff. I wouldn't do it in code that might be reused, even hidden behind an API, but in your case it seems reasonably safe.

Paul Tomblin
I'll upvote that, sounds like common sense to me
David Zaslavsky
Um, everybody using two-digit dates in the 1960s knew that couldn't possibly develop into a problem later....
David Thornley
...and in a tiny memory embedded app, a 2 digit date is probably *still* the right choice.
Paul Tomblin
The problem is you can't always predict when code might be reused. I think it's always a good idea to design your private libraries as if they were going to be public. It's good practice too.
cdmckay
+2  A: 

I'm pretty sure the amount of memory used is negligible. The JVM might even optimize the calls to make them inline depending on the implementation at runtime if you build for production. If you are developing it yourself, it might still help because if you have a difficult to track bug you can set a breakpoint in the getter/setter and see exactly when you are changing the values. It shouldn't be any code to write either because most modern IDE's have functions to generate the code automatically.

Greg
That's another thing I detest about reading Java code...the hundreds and hundreds of lines of useless CRAP code written by IDEs.
Zan Lynx
+1  A: 

It's not stupid, but I'm thinking it's probably not a good idea either.

I understand the temptation...if no one else is ever using the code, then you don't need to worry about it. But time and time again, it turns out this just doesn't match with what actually happens...you find out that you'll be using it in more places than you thought, or the project becomes bigger than expected, or someone just gets ahold of it and thinks it's useful...things that were never meant to be permenant or public have a way of becoming that way.

Is there really that tight a limit on processor power and memory? I don't know about your situation (embedded app, perhaps?), but as an (overgeneralized) rule, you're better off looking elsewhere for resources...in your data structures, algorithms, or archetecture to see better improvements in memory or CPU.

Beska
Wish someone would write a comment in here about why this was downvoted...seems relatively harmless.
Beska
+7  A: 

Chances are good that trivial getters and setters will be inlined anyway - but with public fields you'll have lost the distinction between contract (API) and implementation. Even if this is only an API that you will use, it's good to keep things loosely coupled IMO.

Jon Skeet
+4  A: 

Python folks don't use getters and they're not burning in hell.

Getter/setter is a way to expose part of the class to Java's simple introspection. The Java Bean specification relies on having public getters and setters as a way to determine which attributes are important.

While essential for things that require/produce/use beans, it is not essential feature of OO programming or Java programming. It's just part of the Bean spec, and is required for any class that wants to participate in bean-like things.

Public attributes are fine. They're simple, direct and obvious.

S.Lott
Python does have a convention where "private" members have a common prefix "_". The idea is that you don't use those unless you know what you're doing.
Chase Seibert
@Chase Seibert: While true that _ means "private", we still don't waste much time on writing getters and setters.
S.Lott
The only problem with public attributes is they might be a good idea when you implement them, but may later constrain you down the road when you want greater control over your sets/gets.
cdmckay
@Cameron McKay: (1) Wishing you had put in getters and setters is rare. (2) Unless you're selling your code, you can easily find all the uses for your class and fix them.
S.Lott
The pythonic way of doing unfortunately ishard to apply i the Java world. Simple properties are fine and simple until... you need to refactor, you need to add checks to assignments, you need to proxy... you need to (...)
Newtopian
@Newtopian: if it's hard to refactor your Java code, it might be because you're using the wrong IDE. Seriously. There are many IDE's and a good one makes Java refactoring almost as easy as Python. I prefer NetBeans.
S.Lott
Sounds great, I guess I'll just search and change every single place in my code where a certain property of a class is being assigned. So much easier than just writing a setter to begin with! Plus, everyone can get and set my other property! I'm pretty sure they shouldn't set it, but who cares!
ColinD
@ColinD: My IDE searches and changes all places in the code where I use an attribute. I use NetBeans. And who is "everyone"? I know all of the developers I work with and they can read and understand my code. What kind of environment do you work in?
S.Lott
Even if your IDE does that, I think it makes considerably more sense to have a single method that defines how a property is set rather than have the same thing scattered throughout. Isn't that what DRY is about?
ColinD
@ColinD: That's the point. If the setter is non-trivial, then you really shouldn't be using a naked attribute. My point was that there's no reason to ALWAYS wrap simple attributes with getters and setters. Getters and setters aren't mandatory features of OO programming.
S.Lott
A: 

Any stack use is going to be highly transitory and not a certainty anyway. You may find the compiler optimizes out any unnecessary overhead anyway so you may find you gain nothing in real terms.

I agree it's not necessarily bad for a private non-API class to use public members but what you gain is so small (if there's any at all) I just wouldn't bother.

cletus
+1  A: 

You never know, always code as if the people who read your code know where you live and are serial killers. Even if you develop code only for yourself, try (imo) to do it as if you were developing in a team. This way you get used to build readable best-practice code. As of for the performance overhead, maybe it is better to do it in something like C then if you really really really need every bit of your memory and every cycle of your CPU.

Tomh
A: 

From the perspective of who has written the code and who is going to use it, then it doesn't matter whether its you or anyone else, you might still need getters and setters - if anyone at all uses it later on its a defacto public API.

However, if it really is just data and you don't need any behaviour associated with the class, then by all means have the members public.

To me its whether the class has any behaviour or if you might want to change the names or types of its data members as implementation details that really matters.

As to processor power and memory - have you measured?

quamrana
+23  A: 

If you are replacing getters/setters for performance/memory optimisation, then you are taking the wrong approach. These are almost certainly not going to be the reason your application runs slowly or uses too much memory.

The cardinal sin of optimisation is to do it before you know that you need to. Optimise only when you have real information showing you where the most time/memory is being wasted, and then spend your time optimising that. The thinking behind this is that you will gain more by shaving off 5% of time in a piece of code that takes up 80% of the total run time, than shaving off even 20% in a piece of code that contributes only 5% to the total run time. (Same applies to memory).

Also, I would be careful about designing the application as you suggest, since it will mean that some properties (eg: simple properties) will be directly accessible, while others (more complex derived properties, or properties where you do not want to expose the underlying types) will have getters/setters. So you will end up with a mix of access styles, which will be less maintainable.

KarstenF
+4  A: 

As with any optimisation, measure before and after to see whether there is any benefit that justifies the downsides.

I think that you will find that it won't make any noticeable difference to the performance of your code (but try it for yourself). The JVM will inline frequently used getters and setters.

Use a profiler and find the real hotpsots in your application. Optimisation without evidence is just guesswork.

Dan Dyer
+11  A: 

It is a bad idea to make members publicly available as an optimization. As others have said, it will have virtually no impact. However, if the object is a simple data structure with little behavior, it's fine to write it that way. As long as you're doing it for simplicity and readability, not performance.

Craig P. Motlin
+2  A: 

Consider that once you put something in a public API that it is set in stone. You cannot change the name of it, you cannot change the type of it, you cannot change how it is stored.

Putting it behind a method results in no performance penelty on a modern VM (pretty much anything in the last 10 years).

The flexibility that you gain from having methods to get the value is more important in my opinion,.

If you do decide to make them public make sure that you mark them as final and that they are immutable.

public class Point
{
    public final int x;
    public final int y;

    public Point(final int xVal, final int yVal) 
    {
        x = xVal;
        y = yVal;
    }
}

Edit:

By public API I mean any variable that is public, not that the class itself would be part of the exposed API for other developers. By making it public you can cause yourself issues later on (if it were a "real" public API that other developers had access to it is literally set in stone unless you like breaking other peoples code when you release an update).

TofuBeer
+1  A: 

IMHO, for properties that by their very nature are just meant to passively hold data and couldn't do anything more complicated without completely changing their meaning from the perspective of the API user, getters and setters are just unnecessary boilerplate. If the property is, and by its nature clearly always will be, just a data holder, such as a class that's used similarly to a C struct, just make the stupid thing public. As a more general statement, best practices can easily become a waste of time or even worst practices when applied overzealously without thinking about why they're best practices. Heck, even goto is arguably justified once in a while.

dsimcha
+2  A: 

All the premature optimization issues have been discussed in the previous answers.

I just thought it's worth mentioning that in Java you can imitate C's structs by defining a class with only public members like so:

public class DataClass {
    public int a;
    public String b;
    public char c;
}

and which will be accessed (getting and setting) only by referring to those public members.

This idiom is totally acceptable in some specific scenarios.

Yuval A
I'd prefer using a opaque pointer to that: http://en.wikipedia.org/wiki/Opaque_pointer
TofuBeer
Opaque pointer (or pointers at all) does not exist in Java...
Yuval A
+2  A: 

Getters and setters are not just for protection/privacy. The main use is to change the way you expose the underlying data.

For example, in asp.net c# the visible property of a control may have something such as:

private bool visible = true;

public bool Visible
{
    get
    {
        return visible && Parent.Visible;
    }
    set
    {
        visible = value;
    }
}

The external property (accessor/mutator) has a different meaning to the underlying variable. In addition, if you don't have the above functionality when you begin, when you have simple gets / sets it becomes something that you can add at a later date, easily.

As for the performance point and saving every ounce of processor and memory you can. If this is going to make a noticeable impact then you're probably better off looking at a different language.

Robin Day
+1  A: 

Potential drawbacks for using

public final type var;

instead of

private final type var;

public type getvar() {return var ;}

(which I've personally experienced) include:

  • The prospect -- however unlikely it seems now -- that the representation will need to change, in the base class or in some future subclass.

  • The potential awkwardness of mixing exposed immutably- and mutable-typed fields.

  • The bother of remembering which classes use public final and which use getvar .

  • The bother of explaining this inconsistency to someone else who may later see the source code.

I've just never been able to convince myself that it's worth it, even though I've tried.

joel.neely
A: 

If speed is that critical, it might be worth writing it in C or C++.

Jack BeNimble
Or assembly ? ;-)
OscarRyz
Nah, Java nowadays is pretty darn fast, within epsilon of C/C++. Where Java is really inefficient is in memory usage.
dsimcha
Desktop Java sacrifices memory for speed. Small JVM's like jamvm or squawk use a lot less memory but cannot run so fast.
Thorbjørn Ravn Andersen
+2  A: 

I've never wished I'd had a public field instead of a property, but I can't count the number of times I've wanted a property and had a public field. Eventually you end up wanting logic inside it.

MNGwinn
Exactly... and even if you don't think you will, why not keep the option open?
cdmckay
You shouldn't have logic inside an accessor. I can count a number of times when I've wanted a field and instead a 'property' (an accessor that actually does some other stuff as well) has been exposed.
PintSizedCat
+1  A: 

I have create two small classes, and test them.

  • First I've create a single object as prototype.

  • Then I've create a 2,000,000 array to store them all.

  • Then I've run a loop, create a new instance there and take the values from the prototype.

The average results in seconds comparing each one is:

WithGS  Without
1.1323  1.1116

Diff  = 0.0207 secs.

So, for this case I think it would be much better to have a non-optimized solution first, and once no further requirements are needed, proceed with the profiling.

Here's the code:

PersonGetSet.java


public class PersonGetSet {
    private String name;
    private boolean deceased;

    public void setName( String name ) {
        this.name = name;
    }
    public String getName() {
        return name;
    }

    public void setDeceased( boolean deceased ) {
        this.deceased = deceased;
    }
    public boolean isDeceased() {
        return this.deceased;
    }

    public static void main( String [] args )  {
        PersonGetSet pb = new PersonGetSet();
        pb.setName( "name" );
        pb.setDeceased( true ) ;

        long start = System.currentTimeMillis();
        PersonGetSet [] array = new PersonGetSet[2000000];
        for( int i = 0 ; i < array.length; i++ ) {
            PersonGetSet personGs = new PersonGetSet();
            personGs.setName( pb.getName() );
            personGs.setDeceased( pb.isDeceased() );
            array[i] =  personGs;
        }
        System.out.println( "PersonGetSet took " + ( System.currentTimeMillis() - start ) + " ms. " );
    }
}


Person.java


public class Person {
    String name;
    boolean deceased;
    public static void main( String [] args )  {
        Person pb = new Person();
        pb.name=  "name" ;
        pb.deceased = true;

        long start = System.currentTimeMillis();
        Person [] array = new Person[2000000];
        for( int i = 0 ; i < array.length; i++ ) {
            Person simplePerson = new Person();
            simplePerson.name=  pb.name;
            simplePerson.deceased = pb.deceased;
            array[i] =  simplePerson;
        }
        System.out.println( "Person took " + ( System.currentTimeMillis() - start ) + " ms. " );
    }
}
OscarRyz
I would make the class package local, make the fields final and set them with a constructor. Otherwise, just treat you class as a data structure.
Peter Lawrey
no, this is a better test than you propose Peter. +1
PintSizedCat
Why are you storing your objects in a 2M array each time? Are you testing the GC?
eljenso
@eljenso: Nahh :P I don't really know how much optimization could the VM do, so I keep all the references in the array to avoid the optimizer realize I don't use them ( just in case it has that super-optimization :P )
OscarRyz
+2  A: 

I think the inverse of this question is a better one to ask:

Is it ever a good idea to make an objects members publicly available?

With development, it's generally a good idea to approach things from the principle of using the lowest accessibility level required; in other words, only expose as much data as you need. If you apply this principle generally, then it becomes more of a practice of only sharing as much as is required.

So with that said - why do this?

matt b
A: 

Designing functionally you are never going to need (getters/setters) is just as bad as premature optimisation. If this is really just for your use, don't make it public and then structure it which you believe is the simplest.

Optimisation and/or getters should only be added if you actually need them.

Peter Lawrey
A: 

Do you need the getter at all ? That is to say, should your object be doing work for you, rather than your client getting data values and performing work themselves ?

One key aspect of OOP is telling an object to do something, instead of pulling the bits out and doing it yourself. e.g

double ret = myObj.calculateReturn()

vs.

int v = myObj.getValue();
int ov = myObj.getOldValue();
double ret = (v-ov)/ov * 100; // do I work about dividing by zero etc.?

which I see a lot. Often you do need getters (and setters, perhaps), but when I write a getter I always ask myself whether that data should be exposed, or whether the object should hide it completely for me.

Brian Agnew
A: 

It's always a bad idea to make non-final fields public.

What if you later want to add event notification?

What if you later want to subclass and change the behavior?

What if there are some cross-field constraints you want to enforce?

TofuBeer shows a Point class with final fields -- that's ok. However, the Point class in AWT doesn't use finals, and caused me lots of grief early on in Java.

I was writing some 3D code and wanted to subclass Point such that whenever x & y changed I could automatically adjust z as needed. Because Point's fields were public, there was no way to know when x or y changed!

Scott Stanchfield
+1  A: 

If your priority is performance, you should look into your choice of Java Virtual Machine and how it executes programs. The Desktop Java from Sun spends a LOT of time profiling and compiling java byte code to machine code which results in programs which may run very fast but uses a lot of memory.

If you find that you want to use a HotSpot based JVM, you should look into all the tricks to help it. Getters and setters are usually inlined (i.e. replaced directly in the machine code, instead of a call to a subroutine) and constants are folded. Switch statements for small ranges are usually converted to a jump table.

Normally I find that the "head-under-the-arm" method works well for writing most of the code, and then you profile the running code and find the bottlenecks. I found for instance that StringBuffers are fast for many things, but deleteCharAt(0) is not one of them. Rewriting to use a simple iteration over the string instead of deleting in the string buffer, did wonders. You too, will most likely find that the largest benefits are in algorithms - not small shortcuts.

In the C world the human can hardly outsmart the compiler anymore. In the Java world, the human can help HotSpot by writing straight forward Java.

Thorbjørn Ravn Andersen
A: 

At our team we use the following rule: if the state represented by a class field is mutable then always make it private and provide mutators; however, if it is immutable (i.e. would not be reassigned after class instantiation) then it can be declared as public final [type] [field-name] -- safe for accessing.

Pls note that here "immutable state" specifically means that field is declared as final. Should not be confused with public [immutable-type] [field-name] where one could perform reassignment albeit immutable-type instance is itself immutable.

Pls also note that there are many good reasons to have accessor even for an immutable field. For example, in cases where it is required to perform some action (e.g. security check) at the time when the field is read.

01es
A: 

The argument that this code is only going to be for your own use is a dead easy trap to fall into - this is the case with most code, the publicly exposed bits are usually very small. So assuming most code is for private use, why bother ever using private, protected, final, const (C/C++) - retorical question I know, but I hope the point is clear.

The other thing that is being missed here is locking. If you access the member directly you will only ever be able to lock this code at the whole object or the member level. And that locking will be in the control of the using code, not the Object itself. Maybe OK, maybe not, as in all things it's horses for courses.

A: 

If performance is critical, I would suggest making fields either private if only accessed in the same class or package local if they are accessed in another class. If you give an inner/nested class private fields, the compiler will add/use accessor methods (as the VM does not allow classes to access fields in another class even though Java does)

Having public mutable fields suggests a design issue to me. Having performance critical code split across packages doesn't suggest the sort of tight coding you need for performance critical code.

If you have immutable fields, I don't have a problem making the field public provided you expect a higher development cost if the fields change behaviour. In fact I suggest using public immutable fields, if you believe this makes the code simpler/easier to understand.

However the first priority should still be code readability. The simplest code often performs best as well.

Peter Lawrey