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.
Related
I don't really have a lot of practical experience with either java or oop in general so now I'm stuck with a problem that's probably really easy to work around but where I'm not sure at all how an elegant, oop oriented solution might look like.
So here's a simplified rundown:
Say I wanted to write some sort of calculating application which first of all contains several methods like:
static double sine(double x){...}
static double cosine(double x){...}
and so forth.
Some other static method would then perform some sort of calculation that involves the derivative of one of these functions. If we pretend there was no way to approximate that derivative, the easiest solution that came to mind for me was to wrap each of the method above in a class and to let those classes implement an interface 'Differentiable'
that defines the method 'evaluateDerivative', e.g.:
interface Differentiable {
double evaluateDerivative(double x);
}
class sine implements Differentiable {
static double evaluate(double x){
return...;
}
public double evaluateDerivative(double x) {
return cosine.evaluate(x);
}
}
so if I needed the derivative of any method for another calculation I could simply do something like this:
static double returnDerivativePlusOne(Differentiable d, double x){
return d.evaluateDerivative(x) + 1;
}
Okay, now the problem is this: when I actually want to call the method above, I need an instance of the sine class, e.g.:
DerivativePlusOne(new sine(), 1);
which doesn't really make sense because the sine class only contains static methods (and maybe some final fields) so creating an object seems strange to me.
So, is there a different approach that would produce the same outcome in a more elegant way ? Any help would be appreciated.
Why not make evaluateDerivative function static as well. There is no need of interface.
To make use of polymorphism, we can do the following. Suppose we are doing the following: we have two class Sine and Cosine, and an interface Differentiable.
interface Differentiable {
double evaluateDerivative(double x);
}
class Sine implements Differentiable {
static double evaluate(double x){return...}
public double evaluateDerivative(double x) {return somevalue;}
}
class Cosine implements Differentiable {
static double evaluate(double x){return...}
public double evaluateDerivative(double x) {return somevalue;}
}
In that case, to make use of polymorphism, what you can do is:
Differentiable d = new Sine();
double derivative = d.evaluateDerivate();
d = new Cosine();
derivative = d.evaluateDerivate();
Hope it helps.
Why do you want that methods to be static? And if there is no particular reason, maybe your application should just create an instance of a calculating class at startup, and then use it?
In my opinion, if you really insist on creating objects that provide typical functions and you want to have derivatives of those functions as well, you may hand-code those derived methods (in another or even the same class). I actually can't see where you'd use polymorphism with such case, as this is not a typical oo app (because your objects are just bundles of calculating methods).
What's even more, if you really wanted to create derived classes to calculate derivatives, your evaluateDerivative method should return an object of the derived class, and not a numer.
An elegant solution in this case would be, in my opinion, to create a kind-of-library containing the methods you want. Just an easy-to-use bundle of methods, as your classes does not seem to provide anything more than calculating methods (of typical maths functions, for which there are already written functions as well). I'd still say that created bundle (which may be even a static class) fulfills Single Responsibility Principle (as it only provides some maths functions), but even this does not appear to be so important here. The rules of creating elegant OO solutions (like SOLID rules, for example) are there to help you write code that is easier to manage and handy to build on top of. I can't see how would you build a bigger class hierarchy actually based on your calculating class, so the simplest solution may be the best.
When should I use a constructor and when should I use static method?
Can you explain above with small snippet? I skimmed through a few threads but I'm still not clear with this.
Joshua Bloch advises to favor static factory methods instead of constructors (which I think is a good practice). Couple of advantages and disadvantages :
Advantages of static factory methods :
unlike constructors, they have names
unlike constructors, they are not required to create a new object each time they're invoked (you can cache instances : e.g. Boolean.valueOf(..)
unlike constructors, they can return an object of any subtype of their return type (great flexibility)
Disadvantages of static factory methods :
They are not really distiguishable from other static methods (it's hard to find out how to initialize an object if you are not familiar with the API)
The main disadvantage (if you use only static factory methods, and make constructors private) is that you cannot subclass that class.
Use a public constructor when you only ever want to return a new object that type and you want simplicity.
A good example is StringBuilder as it's mutable and you are likely to want a new object each time.
public String toString() {
StringBuilder sb = new StringBuilder();
// append fields to the sb
return sb.toString();
}
Use a static factor method when you might want to re-use objects (esp if immutable), you might want to return a sub-class or you want descriptice construction. A good example is EnumSet which has a number of static factories which do different things even though some have the same arguments.
EnumSet.noneOf(RetentionPolicy.class);
// has the same arguments, but is not the same as
EnumSet.allOf(RetentionPolicy.class);
In this case, using a static factory makes it clear what the difference between these two ways of construction the set.
Also EnumSet can return two different implementations, one optimised for enums with a small number of values (<= 64) RegularEnumSet and another for many values called JumboEnumSet
Always use a constructor if your class has a state (even for a single instance; singleton pattern ).
Only use static for utility methods like in java.lang.Math
Example:
public static int max(int a, int b) {
return (a >= b) ? a : b;
}
Doesn't change any state (instance variables) of an object, thus it can be declared static.
Use constructor when you need an object and other stuffs like functions and variables having one copy for every object.
when you want to do something without creating object then use static method.
Example:
public class Test {
public int value;
public static int staticValue;
public int getValue() {
return ++value;
}
public static int getStaticValue() {
return ++staticValue;
}
}
public class TestClass {
public static void main(String[] args) {
Test obj = new Test();
Test obj1 = new Test();
S.o.p(obj.getValue());
S.o.p(obj1.getValue));
S.o.p(Test.getStaticValue());
S.o.p(Test.getStaticValue());
}
}
Static factory methods have names, constructors don't. Thus factory methods can carry natural documentation about what they do that constructors can't. For example, see the factory methods in the Guava Libraries, like ImmutableMap.copyOf(otherMap). While this might have little effect on behaviour of construction, it has a huge effect on readability of the code. Definitely consider this if you're publishing an API.
Also you can use a factory when you need to do any more complicated configuration of the object you're creating, especially if you need to publish to other threads (registering in pools, exposing as an MBean, all manner of other things...) to avoid racy publication. (See e.g. Java Concurrency In Practice section 3.2)
Static methods that do something (e.g. Math.min) are not really the same thing as static factories, which can be considered direct replacements for constructors, with added flexibility, evolvability and (often) clarity.
Whenever you need to create an instance of an object you will have to use the constructor.
So, if you want to create a Car object, then you will need a constructor for that.
The keyword static means, that your method can be called without creating an instance.
class Car
{
private int num_of_seats;
public Car(int number_of_seats)
{
this.num_of_seats = number_of_seats;
}
// You want to get the name of the class that has to do with
// this class, but it's not bounded with any data of the class
// itself. So you don't need any instance of the class, and
// you can declare it as static.
static String getClassName()
{
return "[Car]";
}
}
In general you will use static class with data that are not correlated with the instance of the object.
Another example is:
class Ring
{
private List nodes;
public Ring(List nodes)
{
this.nodes = nodes;
}
// You want to calculate the distance of two ids on the ring, but
// you don't care about the ring. You care only about the ids.
// However, this functionality logical falls into the notion of
// the ring, that's why you put it here and you can declare it
// as static. That way you don't have to manage the instance of
// ring.
static double calculateDistance(int id_1, int id_2)
{
return (id_1 - id_2)/383; // The divisor is just random just like the calculation.
}
}
As the posts above say, it's just a matter of what you want to do and how you want to do it. Also, don't try to understand everything rightaway, write some code then try different approaches of that code and try to understand what your code does. Examples are good, but you need to write and then understand what you did. I think it's the only way you will figure out
why you do staff the way you have to do.
Static methods do not have to instantiate new objects everytime. Since object instantiation is expensive it allows instances to be cached within the object. So, it can improve performance.
This is the explanation from the Effective Java :
This allows immutable classes (Item 15) to use preconstructed
instances, or to cache instances as they’re constructed, and dispense
them repeatedly to avoid creating unnecessary duplicate objects. The
Boolean.valueOf(boolean) method illustrates this technique: it never
creates an object. This technique is similar to the Flyweight pattern
[Gamma95, p. 195]. It can greatly improve performance if equivalent
objects are requested often, especially if they are expensive to
create.
i.e. if you want to use a singleton, which means that you have only one instance of the object, which might be shared with others, then you need a static method, which will internally will call the constructor. So, every time someone wants an instance of that object you will return always the same, thus you will consume memory only for one. You always need a constructor in object oriented programming, in every OO language. In java an in many other languages the default constructor of an object is implied, and built automatically. But you need some custom functionality you have to make your own.
Above you see a few good examples of the usage. However, if you have something specific in your mind, please let us know. I mean if you have a specific case where you are not sure if you should use a static method or a constructor. Anyhow, you will definitely need a constructor, but I am not sure about the static method.
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.
When creating classes for "immutable objects" immutable meaning that state of instances can not be changed; all fields assigned in constructor) in Java (and similar languages), it is sometimes useful to still allow creation of modified instances. That is, using an instance as base, and creating a new instance that differs by just one property value; other values coming from the base instance. To give a simple example, one could have class like:
public class Circle {
final double x, y; // location
final double radius;
public Circle(double x, double y, double r) {
this.x = x;
this.y = y;
this.r = r;
}
// method for creating a new instance, moved in x-axis by specified amount
public Circle withOffset(double deltaX) {
return new Circle(x+deltaX, y, radius);
}
}
So: what should method "withOffset" be called? (note: NOT what its name ought to be -- but what is this class of methods called).
Technically it is kind of a factory method, but somehow that does not seem quite right to me, since often factories are just given basic properties (and are either static methods, or are not members of the result type but factory type).
So I am guessing there should be a better term for such methods. Since these methods can be used to implement "fluent interface", maybe they could be "fluent factory methods"?
Better suggestions?
EDIT: as suggested by one of answers, java.math.BigDecimal is a good example with its 'add', 'subtract' (etc) methods.
Also: I noticed that there's this question (by Jon Skeet no less) that is sort of related (although it asks about specific name for method)
EDIT, MAY-2014: My current favorite is mutant factory, FWIW.
I call those types of methods "copy methods".
While the clone() method creates an exact copy, a copy method makes a copy of an instance, usually with an implied or explicit variation. For example, String#toUpperCase() would be a copy method of the immutable String class - it copies an instance with a variation: it upcases all the letters.
I would consider withOffset() method in your example to be a similar copy method.
I don't know of any references that document the term "copy method". I'm borrowing the term "copy" from its use in C++: copy constructors and the "copy" naming guideline from the Taligent Coding Standards (more info).
As for the term "fluent factory methods", I don't know why "fluent" would make a difference, since a "fluent interface" is just an API style (separate from the builder pattern). If the term "factory method" doesn't apply here, I don't see how calling it a "fluent factory method" makes it apply any better.
Hrm … it creates mutated versions of the object … maybe we should call it a mutant factory? :-)
This does not really look like a factory method. The signature alone only tells me that I can chain it in different calls, but not that it is supposed to create a new instance:
I see this use case more like a StringBuilder that allows append("a").append("b").
It could, of course return a new StringBuilder every time (as your Circle does).
So it's not by design a factory. (Think of extracting the interface and writing the JavaDoc for that method: "one must return a new instance, since I'm immutable" -- why so ??) The fact that your class is immutable is just an implementation detail).
EDIT:
Perahs a better example would be BigInteger, since that's also immutable. Along with multiply(BigInteger), it provides a package-private method:
BigInteger multiply(long v)
which returns a new instance and resembles your case very well. That's simply an operation that happens to return a result of the same type as the initial object; not a factory and I don't think this kind of operation really deserves its own name.
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??? :)