Related
Imagine any Java class which is entirely immutable. I will use the following as an example:
public class Point2D {
public final int x;
public final int y;
public Point2D(final int x, final int y) {
this.x = x;
this.y = y;
}
}
Now consider adding an operator on this class: a method which takes one or more instances of Point2D, and returns a new Point2D.
There are two possibilities for this - a static method, or an instance method:
public static Point2D add(final Point2D first, final Point2D second) {
return new Point2D(first.x + second.x, first.y + second.y);
}
or
public Point2D add(final Point2D other) {
return new Point2D(this.x + other.x, this.y + other.y);
}
Is there any reason to pick one over the other? Is there any difference at all between the two? As far as I can tell their behaviour is identical, so any differences must be either in their efficiency, or how easy they are to work with as a programmer.
Using a static method prevents two things:
mocking the class with most mocking frameworks
overwriting the method in a subclass
Depending on context, these things can be okay, but they can also create serious grief in the long run.
Thus, me personally, I only use static when there are really good reasons to do so.
Nonetheless, given the specific Point2D class from the question, I would tend to actually use the static methods. This class smells like it should have "value" semantics, so that two points for the same coordinates are equal and have the same hash code. I also don't see how you would meaningfully extend this class.
Imagine for example a Matrix2D class. There it might make a lot of sense to consider subclasses, such as SparseMatrix for example. And then, most likely, you would want to override computation intensive methods!
There is no practical difference between the two. Where it matters most is in the area of OO design and readability.
The static version of the operation seems more aligned with the static factory pattern. In addition to using a common design pattern, it is a clear creational design, which seems to meet its intent: to create a new object.
On the other hand, instance methods creating new objects are very practical when it comes to immutable objects. The best example of this is the String methods (String.concat(string), etc.). In my opinion, this is more a question of practicality (you don't want to mutate the state of the object; you need to augment the it, but the operation has to result in a new instance).
Is there any reason to pick one over the other?
There may be cases where one fits better than the other (for example, I'd prefer the static method to the instance version in a stream pipeline's reduction - as an example), but there is no evident, absolute preference to be claimed here. So...
I would use the static method for factory operations (although I'd call the method something more like create..., newInstance... for clarity)
I would use the instance method for transformations operations that return new instances to avoid mutating the object.
First and foremost, if it is an immutable make it unsubclassable to others. Usually final is used although you can hide the constructor. Not particularly relevant in this case, but static creation methods allows common values to be reuse instances, specialist implementations to be selected and the ugly diamond (<>) notation to be elided. (If you call your static creation method of it is clear to use when qualified with the type name.)
Addition is usually written as infix. If there are subexpressions involved this will make the client code look much better, though the Java syntax will still force you to have parentheses everywhere. A static method requires qualification or an import static for the client (the latter not really helpful if the method has a name like and, and 'import *' is bad if there other static method that don't make sense without qualification).
Reserve static methods for cases where the object is, in a sense, incidental to the function. For example String's join and format.
As for testing, it should not be necessary to mock a value class or static method. Immutable types should have trusted implementations and therefore not be subtypable by others.
I am reading about the specific guidelines that needs to be followed while creating Immutable Class in Effective Java.
I read that In Immutable class method should not allowed to be overridden otherwise overridden method may change the behaviour of method. Following are the design approaches available in java to solve this problem :-
We can mark class final but as per my understanding, it has a one disadvantage that it makes the class inextensible.
Secondly is to make individual methods final but I can not get other disadvantage besides that we need to individually mark each method as final in order to prevent overridding.
As per book,better approach is to make the constructor private or package-private and provide public static factory method for creating object.
My question is: Even if we include private or default constructor in the class, it cannot be extended anymore in same package (in other package in case of package-private constructor), it has a same problem which the first one had. How is it considered as the better approach than the previous ones?
An immutable object should not be extensible. Why?
Because extending it will allow either direct access to fields (if they are protected which would allow writing methods that change them), or adding state which may be mutable.
Imagine we wrote a class FlexiblyRoundableDouble that extends Double, which has an additional field roundingMode that lets us choose a "rounding mode". You could write a setter for this field, and now your object is mutable.
You can argue that if all the methods are set as final, you cannot change the original behavior of the object. The only methods that could access your roundingMode field are new methods that are not polymorphically available if you assign your object to a Double variable. But when a class's contract says that it's immutable, you make decisions based on that. For example, if you write a clone() method or copy constructor for a class that has Double fields, you know that you don't need to deep-copy the Double fields, as they do not change their state, and can therefore be safely shared between the two clones.
Also, you can write methods that return the internal object without fearing that the caller will then change that object. If the object was mutable, you'd have to make a "defensive copy" of it. But if it's immutable, it's safe to return a reference to the actual internal object.
However, what happens if someone assigned a FlexiblyRoundableDouble to one of your Double fields? That object would be mutable. The clone() would assume it isn't, it will be shared between two objects, perhaps even returned by a method. The caller would then be able to cast it back as a FlexiblyRoundableDouble, change the field... and it will affect other objects that use that same instance.
Therefore, immutable objects should be final.
All this has nothing to do with the constructor issue. Objects can be safely immutable with public constructors (as demonstrated by String, Double, Integer and other standard Java immutables). The static factory method is simply a way utilizing the fact that the object is immutable, and several other objects can hold references to it safely, to create fewer objects with the same value.
Providing a static factory method gives you room to implement the Flyweight Pattern.
They're stating that you should hide the possibility of creating a new object using a constructor, and should rather make a call to a method which checks if an object with similar state exists in the "object pool" (a map filled with objects waiting to be re-used). Not re-using immutable objects is a waste of memory; this is why String literals are encouraged, and new String() is shunned (unless needed).
class ImmutableType {
private static final Map<Definition, ImmutableType> POOL = new HashMap<>();
private final Definition definition;
private ImmutableType(Definition def) {
definition = def;
}
public static ImmutableType get(Definition def) {
if(POOL.contains(def))
return POOL.get(def);
else {
ImmutableType obj = new ImmutableType(def);
POOL.put(def, obj);
return obj;
}
}
}
Definition stores the state of the ImmutableType. If a type with the same definition already exists in the pool, then re-use it. Otherwise, create it, add it to the pool then return it as the value.
As for the statement about marking the class final, immutable types should not be extensible in the first place (to avoid possibly modifying behavior). Marking every method final is just crazy for immutable classes.
I've been reviewing Java Regex Library, surprised by the fact the Pattern class does not have a public constructor which I've taken for granted for years.
One reason I suspect the static compile method is being used in favor of constructor could be that constructor would always return a new object while a static method might return a previously created (and cached) object provided that the pattern string is the same.
However, it is not the case as demonstrated by the following.
public class PatternCompiler {
public static void main(String[] args) {
Pattern first = Pattern.compile(".");
Pattern second = Pattern.compile(".");
if (first == second) {
System.out.println("The same object has been reused!");
} else {
System.out.println("Why not just use constructor?");
}
}
}
Any other strong rationales behind using static method over constructor?
Edit: I found a related question here. None of the answers there convinced me either. Reading through all answers, I get a feeling that a static method has quite a few advantages over a public constructor regarding creating an object but not the other way around. Is that true? If so, I'm gonna create such static methods for each one of my classes and safely assume that it's both more readable and flexible.
Generally, a class won't have a public constructor for one of three reasons:
The class is a utility class and there is no reason to instantiate it (for example, java.lang.Math).
Instantiation can fail, and a constructor can't return null.
A static method clarifies the meaning behind what happens during instantiation.
In the class of Pattern, the third case is applicable--the static compile method is used solely for clarity. Constructing a pattern via new Pattern(..) doesn't make sense from an explanatory point of view, because there's a sophisticated process which goes on to create a new Pattern. To explain this process, the static method is named compile, because the regex is essentially compiled to create the pattern.
In short, there is no programmatic purpose for making Pattern only constructable via a static method.
One possible reason is that this way, caching can later be added into the method.
Another possible reason is readability. Consider this (often cited) object:
class Point2d{
static Point2d fromCartesian(double x, double y);
static Point2d fromPolar(double abs, double arg);
}
Point2d.fromCartesian(1, 2) and Point2d.fromPolar(1, 2) are both perfectly readable and unambiguous (well... apart from the argument order).
Now, consider new Point2d(1, 2). Are the arguments cartesian coordinates, or polar coordinates? It's even worse if constructors with similar / compatible signatures have entirely different semantics (say, int, int is cartesian, double, double is polar).
This rationale applies to any object that can be constructed in multiple different ways that don't differ in just the argument type. While Pattern, currently, can only be compiled from a regex, different representations of a Pattern may come in the future (admittably, then, compile is a bad method name).
Another possible reason, mentioned by #Vulcan, is that a constructor should not fail.
If Pattern.compile encounters an invalid pattern it throws a PatternSyntaxException. Some people may consider it a bad practice to throw an exception from a constructor. Admittably, FileInputStream does exactly that. Similarly, if the design decision was to return null from the compile method, this would not be possible with a constructor.
In short, a constructor is not a good design choice if:
caching may take place, or
the constructor is semantically ambiguous, or
the creation may fail.
This is just a design decision. In this case there is no "real" advantage. However, this design allows optimisation (caching for instance) without changing the API. See http://gbracha.blogspot.nl/2007/06/constructors-considered-harmful.html
Factory methods have several advantages, some of which are already specified in other answers. The advice to consider factory methods instead of constructors is even the very first chapter in the great book "Effective Java" from Joshua Bloch (a must-read for every Java programmer).
One advantage is that you can have several factory methods which have the same parameter signatures but different names. This you can't achieve with constructors.
For example, one might want to create a Pattern from several input formats, all of which are just Strings:
class Pattern {
compile(String regexp) { ... }
compileFromJson(String json) { ... }
compileFromXML(String xml) { ... }
}
Even if you are not doing this when you create the class, factory methods give you the ability to add such methods latter without causing weirdness.
For example, I have seen classes where the need for a new constructor came later and a special meaning-less second parameter had to be added to the second constructor in order to allow overloading. Obviously, this is very ugly:
class Ugly {
Ugly(String str) { ... }
/* This constructor interpretes str in some other way.
* The second parameter is ignored completely. */
Ugly(String str, boolean ignored) { ... }
}
Unfortunately, I can't remember the name of such a class, but I think it even was in the Java API.
Another advantage which has not been mentioned before is that with factory methods in combination with package-private constructors you can prohibit sub-classing for others, but still use sub-classes yourself. In the case of Pattern, you might want to have private sub-classes like CompiledPattern, LazilyCompiledPattern, and InterpretedPattern, but still prohibit sub-classing to ensure immutability.
With a public constructor, you can either prohibit sub-classing for everybody, or not at all.
If you really want to take the deep dive, plunge into the archives of JSR 51.
Regular expressions have been introduced as part of JSR 51, that’s where you might still find the design decisions in their archives, http://jcp.org/en/jsr/detail?id=51
It has a private constructor.
/**
* This private constructor is used to create all Patterns. The pattern
* string and match flags are all that is needed to completely describe
* a Pattern. An empty pattern string results in an object tree with
* only a Start node and a LastNode node.
*/
private Pattern(String p, int f) {
and compile method calls into that.
public static Pattern compile(String regex) {
return new Pattern(regex, 0);
}
Since you are using == comparison which is for references it will not work
The only reason I can think of this behaviour is that the match flag will be defaulted to zero in the compile method which acts a factory method.
First of all please forgive me if its a really dumb question, I am just trying to learn this language to its core. I am reading Effective Java and the very first chapter talks about Static factory methods vs. Constructors. Their pros and cons. Few things that are confusing to me are:
class of an object returned by static factory method is nonpublic - what exactly does it mean?
unlike constructors static factory methods are not required to create a new object each time they are invoked - How does this happen? I am invoking factory method only to obtain a new object and do we put a check in factory method for checking if object already exists?
Thanks.
class of an object returned by static factory method is nonpublic -
what exactly does it mean?
It means that the actual class of the objects returned by a static factory method can be a subclass of the declared type, and this subclass does not have to be public. It's just another implementation detail that client code should not care about.
unlike constructors static factory methods are not required to create a new object each > time they are invoked - How does this happen? I am invoking factory method only to obtain a new object and do we put a check in factory method for checking if object already exists?
Yes, that's one way this could be done. But really, anything is possible.
First off, kudos to you for your choice in Java-lit: Bloch's book is an excellent primer.
To answer your 2nd question ('unlike constructors static factory methods are not required to create a new object each time they are invoked'), it's important to realize that what Bloch is saying here is that with a static factory you have the option of either: returning a new object or returning a pre-existing one. It all depends on what you want to do.
For example, let's suppose you have a really simple value class of type Money. Your static factory method probably should return a new instance -- that is, a new object with a specific value for Money. So, like this:
public class Money {
private Money(String amount) { ... } /* Note the 'private'-constructor */
public static Money newInstance(String amount) {
return new Money(amount);
}
}
But let's say you have some object that manages some resource and you want to synchronize access to that resource through some ResourceManager class. In that case you probably want your static factory method to return the same instance of itself to everyone -- forcing everyone to go through that same instance, so that that 1 instance can control the process. This follows the singleton-pattern. Something like this:
public ResourceManager {
private final static ResourceManager me = new ResourceManager();
private ResourceManager() { ... } /* Note the 'private'-constructor */
public static ResourceManager getSingleton() {
return ResourceManager.me;
}
}
The above method forces your user to only ever be able to use a single instance, allowing you to precisely control who(and when) has access to whatever it is you are managing.
To answer your first question, consider this (admittedly not the best example, it's pretty ad-hoc):
public class Money {
private Money(String amount) { ... }
public static Money getLocalizedMoney( MoneyType localizedMoneyType, String amount ) {
switch( localizedMoneyType ) {
case MoneyType.US:
return new Money_US( amount );
case MoneyType.BR:
return new Money_BR( amount );
default:
return new Money_US( amount );
}
}
}
public class Money_US extends Money { ... }
public class Money_BR extends Money { ... }
Note how I can now do this:
Money money = Money.getLocalizedMoney( user_selected_money_type );
saveLocalizedMoney( money );
Again, a really contrived-example but hopefully it helps you see more or less what Bloch was getting at with that point.
The other answers were good -- I just think that, as a beginner, sometimes it helps to see some actual code.
When you use the new keyword then you as the developer know that the JDK will create a new instace of that object. What the author is saying, when you use a static method, the developer no longer knows if the method is creating a new instance or possibly doing something else. Something else can be, reusing cached data, object pooling, creating a private implementation and returning a subclass of the class.
class of an object returned by static factory method is nonpublic
Frequently a static factory method will return either an an object typed as an interface (most common), or sometimes some base class (less common). In either case, you don't know the exact class of the returned object.
The advantage of this is getting an object whose behaviour you know without worrying about the messy details of what class it instantiates.
unlike constructors static factory methods are not required to create a new object each time they are invoked
To understand this, consider the case of working with a singleton. You may call .getInstance() on some factory classes to get the singleton instance of an certain object. Typically, what this does is create an instance of the object if it doesn't already exist, or give you the existing instance if it already does. In either case, you get back a copy of the object. But you don't (and won't) know if this singleton had to be created, or if one had already been constructed previously.
The advantage of this is that the lifecycle of the object and when it is created is managed for you.
Both of your questions can be answered by looking at some code that makes use of both of these properties of static factory methods. I suggest looking at Guava's ImmutableList.
Note how the no-arg factory method of() always returns the same instance (it doesn't create a new instance each time). If you look carefully, you'll also notice that its copyOf(Iterable) factory method actually returns the object that is passed to it if that object is itself an ImmutableList. Both of these are taking advantage of the fact that an ImmutableList is guaranteed to never change.
Notice also how various factory methods in it return different subclasses, such as EmptyImmutableList, SingletonImmutableList and RegularImmutableList, without exposing the types of those objects. The method signatures just show that they return ImmutableList, and all subclasses of ImmutableList have package-private (default) visibility, making them invisible to library users. This gives all the advantages of multiple implementation classes without adding any complexity from the user's perspective, since they are only allowed to view ImmutableList as a single type.
In addition to ImmutableList, most instantiable classes in Guava utilize static factory methods. Guava also exemplifies a lot of the principles set forth in Effective Java (not surprising, given that it was designed by those principles and with guidance from Josh Bloch himself), so you may find it useful to take a look at it more as you're working through the book.
Is it completely against the Java way to create struct like objects?
class SomeData1 {
public int x;
public int y;
}
I can see a class with accessors and mutators being more Java like.
class SomeData2 {
int getX();
void setX(int x);
int getY();
void setY(int y);
private int x;
private int y;
}
The class from the first example is notationally convenient.
// a function in a class
public int f(SomeData1 d) {
return (3 * d.x) / d.y;
}
This is not as convenient.
// a function in a class
public int f(SomeData2 d) {
return (3 * d.getX()) / d.getY();
}
It appears that many Java people are not familiar with the Sun Java Coding Guidelines
which say it is quite appropriate to use public instance variable when the class is
essentially a "Struct", if Java supported "struct" (when there is no behavior).
People tend to think getters and setters are the Java way,
as if they are at the heart of Java. This is not so. If you follow the Sun Java
Coding Guidelines, using public instance variables in appropriate situations,
you are actually writing better code than cluttering it with needless getters and setters.
Java Code Conventions from 1999 and still unchanged.
10.1 Providing Access to Instance and Class Variables
Don't make any instance or class variable public without good reason. Often, instance variables don't need to be explicitly set or gotten-often that happens as a side effect of method calls.
One example of appropriate public instance variables is the case where the class is essentially a data structure, with no behavior. In other words, if you would have used a struct instead of a class (if Java supported struct), then it's appropriate to make the class's instance variables public.
http://www.oracle.com/technetwork/java/javase/documentation/codeconventions-137265.html#177
http://en.wikipedia.org/wiki/Plain_old_data_structure
http://docs.oracle.com/javase/1.3/docs/guide/collections/designfaq.html#28
Use common sense really. If you have something like:
public class ScreenCoord2D{
public int x;
public int y;
}
Then there's little point in wrapping them up in getters and setters. You're never going to store an x, y coordinate in whole pixels any other way. Getters and setters will only slow you down.
On the other hand, with:
public class BankAccount{
public int balance;
}
You might want to change the way a balance is calculated at some point in the future. This should really use getters and setters.
It's always preferable to know why you're applying good practice, so that you know when it's ok to bend the rules.
This is a commonly discussed topic. The drawback of creating public fields in objects is that you have no control over the values that are set to it. In group projects where there are many programmers using the same code, it's important to avoid side effects. Besides, sometimes it's better to return a copy of field's object or transform it somehow etc. You can mock such methods in your tests. If you create a new class you might not see all possible actions. It's like defensive programming - someday getters and setters may be helpful, and it doesn't cost a lot to create/use them. So they are sometimes useful.
In practice, most fields have simple getters and setters. A possible solution would look like this:
public property String foo;
a->Foo = b->Foo;
Update: It's highly unlikely that property support will be added in Java 7 or perhaps ever. Other JVM languages like Groovy, Scala, etc do support this feature now. - Alex Miller
To address mutability concerns you can declare x and y as final. For example:
class Data {
public final int x;
public final int y;
public Data( int x, int y){
this.x = x;
this.y = y;
}
}
Calling code that attempts to write to these fields will get a compile time error of "field x is declared final; cannot be assigned".
The client code can then have the 'short-hand' convenience you described in your post
public class DataTest {
public DataTest() {
Data data1 = new Data(1, 5);
Data data2 = new Data(2, 4);
System.out.println(f(data1));
System.out.println(f(data2));
}
public int f(Data d) {
return (3 * d.x) / d.y;
}
public static void main(String[] args) {
DataTest dataTest = new DataTest();
}
}
Do not use public fields
Don't use public fields when you really want to wrap the internal behavior of a class. Take java.io.BufferedReader for example. It has the following field:
private boolean skipLF = false; // If the next character is a line feed, skip it
skipLF is read and written in all read methods. What if an external class running in a separate thread maliciously modified the state of skipLF in the middle of a read? BufferedReader will definitely go haywire.
Do use public fields
Take this Point class for example:
class Point {
private double x;
private double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() {
return this.x;
}
public double getY() {
return this.y;
}
public void setX(double x) {
this.x = x;
}
public void setY(double y) {
this.y = y;
}
}
This would make calculating the distance between two points very painful to write.
Point a = new Point(5.0, 4.0);
Point b = new Point(4.0, 9.0);
double distance = Math.sqrt(Math.pow(b.getX() - a.getX(), 2) + Math.pow(b.getY() - a.getY(), 2));
The class does not have any behavior other than plain getters and setters. It is acceptable to use public fields when the class represents just a data structure, and does not have, and never will have behavior (thin getters and setters is not considered behavior here). It can be written better this way:
class Point {
public double x;
public double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
}
Point a = new Point(5.0, 4.0);
Point b = new Point(4.0, 9.0);
double distance = Math.sqrt(Math.pow(b.x - a.x, 2) + Math.pow(b.y - a.y, 2));
Clean!
But remember: Not only your class must be absent of behavior, but it should also have no reason to have behavior in the future as well.
(This is exactly what this answer describes. To quote "Code Conventions for the Java Programming Language: 10. Programming Practices":
One example of appropriate public instance variables is the case where the class is essentially a data structure, with no behavior. In other words, if you would have used a struct instead of a class (if Java supported struct), then it's appropriate to make the class's instance variables public.
So the official documentation also accepts this practice.)
Also, if you're extra sure that members of above Point class should be immutable, then you could add final keyword to enforce it:
public final double x;
public final double y;
By the way, the structure you're giving as an example already exist in the Java base class library as java.awt.Point. It has x and y as public fields, check it out for yourself.
If you know what you're doing, and others in your team know about it, then it is okay to have public fields. But you shouldn't rely on it because they can cause headaches as in bugs related to developers using objects as if they were stack allocated structs (java objects are always sent to methods as references and not as copies).
Re: aku, izb, John Topley...
Watch out for mutability issues...
It may seem sensible to omit getters/setters. It actually may be ok in some cases. The real problem with the proposed pattern shown here is mutability.
The problem is once you pass an object reference out containing non-final, public fields. Anything else with that reference is free to modify those fields. You no longer have any control over the state of that object. (Think what would happen if Strings were mutable.)
It gets bad when that object is an important part of the internal state of another, you've just exposed internal implementation. To prevent this, a copy of the object must be returned instead. This works, but can cause massive GC pressure from tons of single-use copies created.
If you have public fields, consider making the class read-only. Add the fields as parameters to the constructor, and mark the fields final. Otherwise make sure you're not exposing internal state, and if you need to construct new instances for a return value, make sure it won't be called excessively.
See: "Effective Java" by Joshua Bloch -- Item #13: Favor Immutability.
PS: Also keep in mind, all JVMs these days will optimize away the getMethod if possible, resulting in just a single field-read instruction.
I have tried this in a few projects, on the theory that getters and setters clutter up the code with semantically meaningless cruft, and that other languages seem to do just fine with convention-based data-hiding or partitioning of responsibilities (e.g. python).
As others have noted above, there are 2 problems that you run into, and they're not really fixable:
Just about any automated tool in the java world relies on the getter/setter convention. Ditto for, as noted by others, jsp tags, spring configuration, eclipse tools, etc. etc...
Fighting against what your tools expect to see is a recipe for long sessions trolling through google trying to find that non-standard way of initiating spring beans. Really not worth the trouble.
Once you have your elegantly coded application with hundreds of public variables you will likely find at least one situation where they're insufficient- where you absolutely need immutability, or you need to trigger some event when the variable gets set, or you want to throw an exception on a variable change because it sets an object state to something unpleasant. You're then stuck with the unenviable choices between cluttering up your code with some special method everywhere the variable is directly referenced, having some special access form for 3 out of the 1000 variables in your application.
And this is in the best case scenario of working entirely in a self-contained private project. Once you export the whole thing to a publicly accessible library these problems will become even larger.
Java is very verbose, and this is a tempting thing to do. Don't do it.
If the Java way is the OO way, then yes, creating a class with public fields breaks the principles around information hiding which say that an object should manage its own internal state. (So as I'm not just spouting jargon at you, a benefit of information hiding is that the internal workings of a class are hidden behind an interface - say you wanted to change the mechanism by which your struct class saved one of its fields, you'll probably need to go back and change any classes that use the class...)
You also can't take advantage of the support for JavaBean naming compliant classes, which will hurt if you decide to, say, use the class in a JavaServer Page which is written using Expression Language.
The JavaWorld article Why Getter and Setter Methods are Evil article also might be of interest to you in thinking about when not to implement accessor and mutator methods.
If you're writing a small solution and want to minimise the amount of code involved, the Java way may not be the right way - I guess it always depends on you and the problem you're trying to solve.
There is nothing wrong with that type of code, provided that the author knows they are structs (or data shuttles) instead of objects. Lots of Java developers can't tell the difference between a well-formed object (not just a subclass of java.lang.Object, but a true object in a specific domain) and a pineapple. Ergo,they end up writing structs when they need objects and viceversa.
A very-very old question, but let me make another short contribution. Java 8 introduced lambda expressions and method references. Lambda expressions can be simple method references and not declare a "true" body. But you cannot "convert" a field into a method reference. Thus
stream.mapToInt(SomeData1::x)
isn't legal, but
stream.mapToInt(SomeData2::getX)
is.
The problem with using public field access is the same problem as using new instead of a factory method - if you change your mind later, all existing callers are broken. So, from an API evolution point of view, it's usually a good idea to bite the bullet and use getters/setters.
One place where I go the other way is when you strongly control access to the class, for example in an inner static class used as an internal data structure. In this case, it might be much clearer to use field access.
By the way, on e-bartek's assertion, it is highly unlikely IMO that property support will be added in Java 7.
I frequently use this pattern when building private inner classes to simplify my code, but I would not recommend exposing such objects in a public API. In general, the more frequently you can make objects in your public API immutable the better, and it is not possible to construct your 'struct-like' object in an immutable fashion.
As an aside, even if I were writing this object as a private inner class I would still provide a constructor to simplify the code to initialize the object. Having to have 3 lines of code to get a usable object when one will do is just messy.
I don't see the harm if you know that it's always going to be a simple struct and that you're never going to want to attach behaviour to it.
This is a question on Object Oriented Design, not Java the language. It's generally good practice to hide data types within the class and expose only the methods that are part of the class API. If you expose internal data types, you can never change them in the future. If you hide them, your only obligation to the user is the method's return and argument types.
Sometime I use such class, when I need to return multiple values from a method. Of course, such object is short lived and with very limited visibility, so it should be OK.
You can make a simple class with public fields and no methods in Java, but it is still a class and is still handled syntactically and in terms of memory allocation just like a class. There is no way to genuinely reproduce structs in Java.
As with most things, there's the general rule and then there are specific circumstances.
If you are doing a closed, captured application so that you know how a given object is going to be used, then you can exercise more freedom to favor visibility and/or efficiency.
If you're developing a class which is going to be used publicly by others beyond your control, then lean towards the getter/setter model.
As with all things, just use common sense.
It's often ok to do an initial round with publics and then change them to getter/setters later.
Aspect-oriented programming lets you trap assignments or fetches and attach intercepting logic to them, which I propose is the right way to solve the problem. (The issue of whether they should be public or protected or package-protected is orthogonal.)
Thus you start out with unintercepted fields with the right access qualifier. As your program requirements grow you attach logic to perhaps validate, make a copy of the object being returned, etc.
The getter/setter philosophy imposes costs on a large number of simple cases where they are not needed.
Whether aspect-style is cleaner or not is somewhat qualitative. I would find it easy to see just the variables in a class and view the logic separately. In fact, the raison d'etre for Apect-oriented programming is that many concerns are cross-cutting and compartmentalizing them in the class body itself is not ideal (logging being an example -- if you want to log all gets Java wants you to write a whole bunch of getters and keeping them in sync but AspectJ allows you a one-liner).
The issue of IDE is a red-herring. It is not so much the typing as it is the reading and visual pollution that arises from get/sets.
Annotations seem similar to aspect-oriented programming at first sight however they require you to exhaustively enumerate pointcuts by attaching annotations, as opposed to a concise wild-card-like pointcut specification in AspectJ.
I hope awareness of AspectJ prevents people from prematurely settling on dynamic languages.
Here I create a program to input Name and Age of 5 different persons and perform a selection sort (age wise). I used an class which act as a structure (like C programming language) and a main class to perform the complete operation. Hereunder I'm furnishing the code...
import java.io.*;
class NameList {
String name;
int age;
}
class StructNameAge {
public static void main(String [] args) throws IOException {
NameList nl[]=new NameList[5]; // Create new radix of the structure NameList into 'nl' object
NameList temp=new NameList(); // Create a temporary object of the structure
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
/* Enter data into each radix of 'nl' object */
for(int i=0; i<5; i++) {
nl[i]=new NameList(); // Assign the structure into each radix
System.out.print("Name: ");
nl[i].name=br.readLine();
System.out.print("Age: ");
nl[i].age=Integer.parseInt(br.readLine());
System.out.println();
}
/* Perform the sort (Selection Sort Method) */
for(int i=0; i<4; i++) {
for(int j=i+1; j<5; j++) {
if(nl[i].age>nl[j].age) {
temp=nl[i];
nl[i]=nl[j];
nl[j]=temp;
}
}
}
/* Print each radix stored in 'nl' object */
for(int i=0; i<5; i++)
System.out.println(nl[i].name+" ("+nl[i].age+")");
}
}
The above code is Error Free and Tested... Just copy and paste it into your IDE and ... You know and what??? :)