Related
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.
To make a class immutable what I can do is:
1)Make class final
2)do not provide setters
3)mark all variables as final
But if my class has another object of some other class then , somone can change value of that object
class MyClass{
final int a;
final OtherClass other
MyClass(int a ,OtherClass other){
this.a = a;
this.other = other;
}
int getA(){
return a;
}
OtherClass getOther(){
return other;
}
public static void main(String ags[]){
MyClass m = new Myclass(1,new OtherClass);
Other o = m.getOther();
o.setSomething(xyz) ; //This is the problem ,How to prevent this?
}
}
A) Make the OtherClass immutable as well
or
B) Don't allow direct access to the OtherClass object, instead providing only getters to act as a proxy.
Edit to add: You could make a deep copy of OtherClass and return a copy rather than the original, but that generally isn't the type of behavior you would expect in Java.
Immutability is best considered from the perspective of the API user. So your object API needs to satisfy the following two conditions:
No way for an external user to change the value of the object
A guarantee that any time the user reads or makes use of the object's value in the future, it will get the same result
Important note: It is in fact OK to have mutable data inside an immutable object as long as it behaves as an immutable object from the perspective of the API user. Consider java.lang.String for example: although it is generally considered as the definitive immutable class, it does in fact have a mutable internal field for caching the hashCode (not many people know this!).
So to address your question, if you wish to contain another (mutable) object inside an immutable object then you typically need to do one or more of the following:
Guarantee that nobody else can change the value of the mutable object. Typically this means ensuring that no-one else can have a reference to the mutable object, so this is only usually possible if you create the object yourself rather than accept a reference from outside.
Take a defensive deep copy of the mutable object, and don't hand out references to the new copy. Only allow operations that read the new copy in the public API. If you need to hand out a reference to this object, then you need to take another defensive copy (to avoid handing out a reference to the internal copy).
Use an immutable wrapper for the mutable object. Something like Collections.unmodifiableList. This is useful if you want to hand out a reference to the internal mutable object but don't want to run the risk of it being modified.
All of these solutions are a bit hacky - a better solution overall is to avoid the use of mutable objects within immutable objects. In the long run it's asking for trouble because sooner or later a mutable reference will leak out and you will have an extremely hard to find bug. You are better moving towards a full hierarchy of immutable objects (the approach taken by languages like Scala and Clojure)
I assume OtherClass (by the way you say Other once) is meant to be a class you don't control, or which has to have a setter.
If you can't remove getOther, change it to getOtherView and return a read-only view of other. There will be wrappers for all the get methods, but no set ones.
Return deep clones from your getters. You may find this to be no easy task.
All the objects referenced in the immutable class should be immutable, or at least be encapsulated as private and making sure that they are not modified (not inside the methods of your class and definitely not from the outside). For instance, if you have this situation:
public class MyImmutable {
private MutableClass mutableObject;
}
... You can not provide the getMutableObject() method, because doing so will open the door for outside modifications, like this:
myImmutable.getMutableObject().setSomeAttribute(newValue);
As a special case of the above, all collections and/or maps should be made immutable, with the ummodifiableXXX() methods in the Collections class.
you cannot (reasonably) stop that in java. if you don't have control over the other class, there are ways to effectively get immutable behavior, but it can be very expensive in practice. basically, you must always return a copy of that class in any public method return values. (the jdk actually has this problem with the TimeZone class).
But If my class has another object of some other class then , somone
can change value of that object...
Java objects are not primitive. If you mark a primitive as final, then its value cannot be changed once it is assigned. However, object contents cannot be final, only object references can be final. So you cannot make an object in this way.
One solution might be abandoning all setter/mutator methods those could change the particular fields of the object and encapsulating them in a way that you can only access them, not change them.
It is possible to create the immutable class in java by following ways
1.Don't Provide setter methods.
2.Make all fields are as final and private.
3.Make Class as final.
I have a class TimeLine in my GUI. I have a function where I would like to copy this TimeLine and modify the data in it whithout the TImeLine in my GUI won't be affected.
I've searched some forums and haven't found an easy way because Java let's the references stick. Why isn't there a easy way to create a new Object (TimeLine) that hasn't the reference to the previous one?
Please help my make a copy of this TimeLine object!
The clone() method and Cloneable interface, suggested by other authors here, were created with the incorrect assumption that it would be a good idea to have a generic copying method. The default implementations does a shallow clone of the current object, but you could override it to do a deep clone.
There is no correct, generic way to copy arbitrary objects, what you want to copy depends on the objects involved. For example, immutable objects never need copying (that'd just be a waste of space), while some types of objects can't be copied (how would you copy a FileOutputStream, for example?).
The way I find most elegant is immutable objects with methods that return a copy with just one field changed:
class Pony {
private final String name;
private final Color color;
private final int tailLength;
// constructors and accessors omitted
Pony withName(String newName) {
return new Pony(newName, color, tailLength);
}
Pony withColor(Color newColor) {
return new Pony(name, newColor, tailLength);
}
Pony withTailLength(String newTailLength) {
return new Pony(name, color, newTailLength);
}
}
// Usage:
Pony tony = new Pony("Tony", Color.DAPPLE, 32);
Pony maurice = tony.withName("Maurice") // Maurice is like Tony, but black.
.withColor(Color.BLACK);
Unfortunately, you get a lot of boilerplate this way, and there's no mainstream IDE support either (there may be plugins, though). Related to this is the Builder pattern recommended by Josh Bloch in Effective Java.
Instead of clone() you might want to consider writing a copy constructor for your class:
public TimeLine(TimeLine original) {
this.foo = original.foo;
this.bar = original.bar;
}
Be careful when copying the value of any reference fields in your class. Be sure whether you want a shallow copy or a deep copy.
In Java using the operator "=" your are simply copying references to objects. If you want to implement copy by value use clone operation (clone() method of the class Object) or implement your own clone method (overriding the implemented one).
Pay attention that if your class stores other object inside it, these objects should eventually be cloned too (DEEP COPY).
if you want to copy an object use clone()
if I misunderstood your question please comment
You're looking for the clone method. (I've gone back and forth as to which documentation to cite, that is Wikipedia, it's treatment is more thorough. The Java doc's are more official, of course).
Eg.
MyObject a = new MyObject();
a.setSomething( 2 );
MyObject b = a.clone();
// now b.getSomething().equals(a.getSomething()) (maybe == too, depends on class)
// and b.equals(a)
// b != a
Ok, this might be basic, but I want good programmers' opinions on this.
What is a good way to handle variables in a small class file?
I like modularizing methods and keeping methods that do really specific things.
I end up passing variables between those methods. Is it a good practice to make variables used across many methods as member variables? Or is it better to pass the variables to methods?
For example:
class Test{
somefunction(int a, int b, int c, int d) {
doSomething(a, b, c);
doOneMoreThing(a, c, d);
}
void doSomething(int a, int b, int c) { }
void doOneMoreThing(int a, int c, int d) { }
}
In the above example, do you think the variables should be kept as member variables?
Please explain why one methodology is preferred over the other.
Do you need to keep the variables around between method calls, and reuse their value? If so, they should be class members. (At least in some class - not necessarily this one.)
Otherwise it is somewhat a matter of taste. One important factor is though that local variables don't add state to the object, which can be useful if it is used concurrently. Keeping all variables local may even allow you to make your class immutable, which usually makes it automatically thread-safe. But even in a single-threaded environment an immutable class is easier to understand and maintain.
OTOH passing lots of parameters around can be awkward. You may consider introducing a Parameter Object to alleviate this problem.
If I have some variables that I would end up passing to a bunch of private methods, I'll often move them into a private inner worker class.
Instead of
class Foo {
public doSomething(...) {
// some setup
doSomethingRecursively(a, b, c);
}
private void doSomethingRecursively(A a, B b, C c) {
if (baseCase) { ... }
doSomethingRecursively(a + 1, b, c);
}
}
I'll move the variables that never difference into properties on a worker.
class Foo {
public doSomething(...) {
// some setup
new AppropriatelyNamedHelper(b, c).doSomethingRecursively(a);
}
private static final class AppropriatelyNamedHelper {
final B b;
final C c;
AppropriatelyNamedHelper(B b, C c) {
this.b = b;
this.c = c;
}
void doSomethingRecursively(A a) {
if (baseCase) { ... }
doSomethingRecursively(a + 1);
}
}
}
This makes it clear to a reviewer what in each scope is invariant within that scope.
Member variables should exist to maintain some kind of state in a class. If your class maintains state then definitely define member variables for those things you need to track. If a class does not maintain state then there is no reason to make things members (I have had to debug legacy code where variables should not have been made members but were and it was causing errors when making multiple calls to the object because the state was unpredictable).
However, while you might like "modularizing" functionality, read up on coupling vs. cohesion. There is a balance to be struck between having too much functionality in a class but fewer dependencies and having very little but highly specific functionality and lots of dependencies.
Having useless member variables is usually regarded to as bad design.
But you can (and should) combine multiple variable sets into a new class if you use that variables in lots of methods.
If you don't care about the state of the object, then passing the variables to the method is fine. In that case, I would use a static modifier on the method, then you don't have to instansiate the class and you can call the method like so:
Test.doSomething(1, 2, 3);
Instance Variables: Their values are unique to each instance of a class. When an object is allocated in the heap, there is a slot in it for each instance variable value. Therefore an instance variable is created when an object is created and destroyed when the object is destroyed.
Class Variable: The Class variables are declared with a static keyword/modifier.There is only one copy of class variable no matter how many times the class is instantiated. They are stored in static memory.
Local variables: Only accessible within the method they are declared. When a method is entered, an area is pushed onto the call stack. This area contains slots for each local variable and parameter. When the method is called, the parameter slots are initialized to the parameter values. When the method exits, this area is popped off the stack and the memory becomes available for the next called method.
If you are going to reuse the variables, then you can declare them as class variables. If not, then they should be local variables defined in their respective methods.
First of all Somefunction(... } is a syntax error. Second, method names should start with lower case letters, and class names should start with upper case. Third, we have no idea what the best way is without knowing what these methods do, what they're used for, and where their parameters come from
Depends on how often you have to change your code (or you should think about how often you're going to change it when you design it). If the signature changes you have to change it in a lot of places. That means more code to test even when you refactor the signature. I would err on the side of creating member variables and encapsulating.
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??? :)