What's the difference between anonymous classes in Java and closures? - java

It looks like anonymous class provides the basic functionality of closure, is that true?

There is almost no difference. In fact the there is an old saying about closures and objects. Closures are the poor man's object, and objects are the poor man's closure. Both are equally powerful in terms of what they can do. We are only arguing over expressiveness.
In Java we are modeling closures with Anonymous Objects. In fact a little history here is that originally Java had the ability to modify the outward scope without the use of final. This works and worked fine for Objects allocated in the local method scope, but when it comes to primitives this caused lots of controversy. Primitives are allocated on the stack so in order for them to live past the execution of the outer method Java would have to allocate memory on the heap and move those members into the heap. At that time people were very new to garbage collection and they didn't trust it so the claim was Java shouldn't allocate memory without explicit instruction from the programmer. In efforts to strike a compromise Java decided to use the final keyword.
http://madbean.com/2003/mb2003-49/
Now the interesting thing is that Java could remove that restriction and make use of the final keyword optional now that everyone is more comfortable with the garbage collector and it could be completely compatible from a language perspective. Although the work around for this issue is simple to define instance variables on your Anonymous Object and you can modify those as much as you wish. In fact that could be an easy way to implement closure style references to local scope by adding public instance variables to the anonymous class through the compiler, and rewriting the source code to use those instead of stack variables.
public Object someFunction() {
int someValue = 0;
SomeAnonymousClass implementation = new SomeAnonymousClass() {
public boolean callback() {
someValue++;
}
}
implementation.callback();
return someValue;
}
Would be rewritten to:
public Object someFunction() {
SomeAnonymousClass implementation = new SomeAnonymousClass() {
public int someValue = 0;
public boolean callback() {
someValue++;
}
}
implementation.callback();
// all references to someValue could be rewritten to
// use this instance variable instead.
return implementation.someValue;
}
I think the reason people complain about Anonymous inner classes has more to do with static typing vs dynamic typing. In Java we have to define an agreed upon interface for the implementor of the anonymous class and the code accepting the anonymous class. We have to do that so we can type check everything at compile time. If we had 1st class functions then Java would need to define a syntax for declaring a method's parameters and return types as a data type to remain a statically typed language for type safety. This would almost be as complex as defining an interface. (An interface can define multiple methods, a syntax for declaring 1st class methods would only be for one method). You could think of this as a short form interface syntax. Under the hood the compiler could translate the short form notation to an interface at compile time.
There are a lot of things that could be done to Java to improve the Anonymous Class experience without ditching the language or major surgery.

As far as they both affect otherwise "private" scoping, in a very limited sense, yes. however, there are so many differences that the answer might as well be no.
Since Java lacks the ability to handle blocks of code as true R-values, inner classes cannot pass blocks of code as is typically done in continuations. Therefore the closure as a continuation technique is completely missing.
While the lifetime of a class to be garbage collected is extended by people holding inner classes (similar to closures keeping variables alive while being rebound to the closure), the ability of Java to do renaming via binding is limited to comply with the existing Java syntax.
And to allow threads to properly not stomp over each other's data using Java's thread contention model, inner classes are further restricted with access to data that is guaranteed not to upset, aka final locals.
This completely ignores the other inner classes (aka static inner classes) which is slightly different in feel. In other words, it touches upon a few items that closures could handle, but falls short of the minimum requirements that most people would consider necessary to be called a closure.

IMHO, They serve a similar purpose, however a closure is intended to be more concise and potentially provide more functionality.
Say you want to use a local variable using an anonymous class.
final int[] i = { 0 };
final double[] d = { 0.0 };
Runnable run = new Runnable() {
public void run() {
d[0] = i[0] * 1.5;
}
};
executor.submit(run);
Closures avoid the need for most of the boiler plate coding by allowing you write just what is intended.
int i = 0;
double d = 0.0;
Runnable run = { => d = i * 1.5; };
executor.submit(run);
or even
executor.submit({ => d = i * 1.5; });
or if closures support code blocks.
executor.submit() {
d = i * 1.5;
}

Related

Local Type Inference vs Instance

I've tried to scan JEP-286 about local type inference. I see that this works only for local variables - understood. So this does work indeed:
public class TestClass {
public static void main(String [] args){
var list = new ArrayList<>();
list.add("1");
System.out.println(list.get(0)); // 1
}
}
I do see that this on the other hand does not compile:
public class TestClass {
public var list = new ArrayList<>();
public static void main(String [] args){
}
}
It's obvious that it does not, since the JEP says so. Now my question:
It makes perfect sense for a public/protected member declared as var to fail, at least IMO. But why does it not compile even if it's private? I can only assume that you can still get a hold of that variable via reflection (and I can't get local fields like this)... And getting that variable would require a cast, well, a very confused cast probably.
The motivation for forbidding type inference for fields and method returns is that APIs should be stable; field access and method invocation are linked by descriptor at runtime, so things that cause subtle changes to inferred types could cause existing compiled clients to break in terrible ways if a change to the implementation caused the inferred type to change (modulo erasure.) So using this for implementation, but not for API, is a sensible guiding principle.
It is reasonable to ask "so, what about private fields and methods?" And indeed, we could well have chosen to do that. Like all design decisions, this is a tradeoff; it would enable inference to be used in more places, in exchange for more complexity in the user model. (I don't care as much about complexity in the spec or the compiler; that's our problem.) It is easier to reason about "inference for local variables yes, fields and methods no" than adding various epicyclic considerations like "but, fields and methods are OK if they are private". Drawing the line where we did also means that the compatibility consequences of changing a field or method from private to nonprivate doesn't have accidental interactions with inference.
So the short answer is, doing it this way makes the language simpler, without making the feature dramatically less useful.
Various reasons:
Visibility and type are orthogonal - one shouldn't impact the other. If private variables could be initialized with var, you'd had to change that when making them protected or public.
Because var uses the right-hand side to infer the type, such private fields always needed to be initialized right away. If moving initialization into a constructor, you'd have to make the type explicit.
With var the compiler can infer types that you can currently can't express in Java (e.g. intersection types like Comparable & Serializable). You might of course end up relying on those specific types and when you have to stop using var at some point for any reason, you might have to refactor quite a lot to keep your code working.
It’s not like it was entirely impossible to turn these variables into fields that can be inspected via Reflection. E.g., you can do
var l = new ArrayList<String>();
l.add("text");
System.out.println(l);
System.out.println(
new Object(){ { var x = l; } }.getClass().getDeclaredFields()[0].getGenericType()
);
In the current version, it just prints ArrayList, so the actual generic type has not been stored in the class file of the anonymous inner class and it’s unlikely that this will change, as supporting this introspection is not an the actual goal. It’s also just a special case that the type is denotable like ArrayList<String>. To illustrate a different case:
var acs = true? new StringBuilder(): CharBuffer.allocate(10);
acs.append("text");
acs.subSequence(1, 2);
System.out.println(
new Object(){ { var x = acs; } }.getClass().getDeclaredFields()[0].getGenericType()
);
The type of acs is an intersection type of Appendable and CharSequence, as demonstrated by invoking a method of either interface on it, but since it is not specified whether the compiler infers #1 extends Appendable&CharSequence or #1 extends CharSequence&Appendable, it is unspecified whether the code will print java.lang.Appendable or java.lang.CharSequence.
I don’t think that this is an issue for a synthetic field, but for an explicitly declared field, it might be.
However, I doubt that the expert group considered such impacts en detail. Instead, the decision not to support field declarations (and hence skip lengthy thinking about the implications) was made right from the start, as local variables always were the intended target for that feature. The number of local variables is much higher than the number of field declarations, so reducing the boilerplate for local variable declarations has the biggest impact.
Elaborating on Nicolai's answer (specifically his #2 reason), the proposed draft of JLS 10 states that both var e; and var g = null; are illegal for local variables, and for good reason; it's not clear from the right-hand side (or lack thereof) which type to infer for var.
Currently, non-final instance variables are automatically initialized depending on their type (primitives to 0 and false, and references to null, as I'm sure you already know). The inferred type of an instance variable would remain unclear unless it is initialized at declaration or within its respective class' constructor(s).
For that reason, I support allowing var to be used only when the variable is both private and final so we can ensure that it is initialized by the time that the class is created. Though, I cannot say how difficult this would be to implement.
It would be a reasonable decision to allow var for private fields (IMO). But omitting it makes the feature simpler.
Also it can be added in some future release after there is more experience with the local-only type inference, while removing a feature is much harder.

Why does having static members make a language less object-orientated?

I'm learning Scala at the moment and I came across this statement in Odersky's Programming Scala 2nd edition:
one way in which Scala is more object-orientated than Java is that classes in Scala cannot have static members.
I'm not sufficiently experienced in either Java or Scala to understand that comparison. Why does having static members make a language less OO?
Odersky's statement is valid and significant, but some people don't understand what he meant.
Let's say that in Java you have a class Foo with method f:
class Foo {
int f() { /* does something great */ }
}
You can write a method that takes a Foo and invokes f on it:
void g(Foo foo) { foo.f(); }
Perhaps there is a class SubFoo that extends Foo; g works on that too. There can be a whole set of classes, related by inheritance or by an interface, which share the fact that they can be used with g.
Now let's make that f method static:
class Foo {
static int f() { /* does something great */ }
}
Can we use this new Foo with g, perhaps like so?
g(Foo); // No, this is nonsense.
Darn. OK, let's change the signature of g so that we can pass Foo to it and have it invoke f.
Ooops -- we can't. We can't pass around a reference to Foo because Foo is not an instance of some class. Some people commenting here are confused by the fact that there is a Class object corresponding to Foo, but as Sotirios tried to explain, that Class object does not have an f method and Foo is not an instance of that class. Foo is not an instance of anything; it is not an object at all. The Class object for Foo is an instance of class Class that has information about Foo (think of it as Foo's internal Wikipedia page), and is completely irrelevant to the discussion. The Wikipedia page for "tiger" is not a tiger.
In Java, "primitives" like 3 and 'x' are not objects. They are objects in Scala. For performance your program will use JVM primitives for 3 and 'x' wherever possible during execution, but at the level you code in they really are objects. The fact that they are not objects in Java has rather unfortunate consequences for anyone trying to write code that handles all data types -- you have to have special logic and additional methods to cover primitives. If you've ever seen or written that kind of code, you know that it's awful. Odersky's statement is not "purism"; far from it.
In Scala there is no piece of runtime data that is not an object, and there is no thing you can invoke methods on that is not an object. In Java neither of these statements in true; Java is a partially object-oriented language. In Java there are things which are not objects and there are methods which aren't on objects.
Newcomers to Scala often think of object Foo as some weird replacement for Java statics, but that's something you need to get past quickly. Instead think of Java's static methods as a non-OO wart and Scala's object Foo { ... } as something along these lines:
class SomeHiddenClass { ... }
val Foo = new SomeHiddenClass // the only instance of it
Here Foo is a value, not a type, and it really is an object. It can be passed to a method. It can extend some other class. For example:
abstract class AbFoo { def f:Int }
object Foo extends AbFoo { def f = 2 }
Now, finally, you can say
g(Foo)
It is true that a "companion object" for a class is a good place to put non-instance methods and data for the class. But that companion object is an object, so the usual rules and capabilities apply.
The fact that in Java you put such methods on non-objects -- limiting how they can be used -- is a liability, not a feature. It is certainly not OO.
I am not sure I completely buy that argument, but here is one possible reasoning.
To an object-oriented purist, everything should be an object, and all state should be encapsulated by objects. Any static member of a class is by definition state which exists outside of an object, because you can use it and manipulate it without instantiating an object. Thus, the lack of static class members makes for a more pure object-oriented language.
Well, with static members like methods you don't have any objects to create and nevertheless you can call such static methods. You only need the static classname in order to set the namespace for these methods, for example:
long timeNow = System.currentTimeMillis(); // no object creation
This rather gives a feeling like in procedural languages.
static members belongs to the Class not to the object while the main concept of oop lies among the relation between the individual objects of dirrefer Class.
A static method in Java is one that operates on the class itself, and doesn't need an Object to be created first. For example, this line:
int c = Integer.parseInt("5");
Integer.parseInt() is static because I didn't have to go Integer i = new Integer(); before using it; this isn't operating on any particular object that I've created, since it's always going to be the same, and is more like a typical procedural function call instead of an object-oriented method. It's more object-oriented if I have to create an object for every call and we encapsulate everything that way instead of allowing static to use methods as faux-procedural-functions.
There are several competing definitions of what exactly object-orientation means. However, there is one thing they all can agree on: dynamic dispatch is a fundamental part of the definition of OO.
Static methods are static (duh), not dynamic, ergo they are by definition not object-oriented.
And logically, a language that has a feature which isn't object-oriented is in some sense "less OO" than a language which doesn't have said feature.

How much more expensive is the creation of an object without data in Java instead of the use of static methods?

Java lacks the ability to specify interfaces for static methods. A method in an interface must be non static. This makes it impossible to specify requirements for Classes. Instead one is limited to specify requirements for Objects. This makes it also impossible for example to specify the singleton functionality in an interface, because in Java the singleton pattern requires to be implemented as a static method. Here is a nice article, which explains it, but it is only in German.
When one is forced to implement something as a functionality of an object instead of the functionality of a class, an instance of this object has to be created, before the functionality can be used. But such object has some special characteristic: it has no state, because class functionality has no state either. Theoretically the instance creation of an object without data can be optimized to an NOP, because all methods can be linked to the class instead of any object. Java could implement some kind of implicit singleton functionality.
But how it this actually handled?
Think about some kind of functionality without any state.
interface Adder<T> { T add(T ... arguments); }
Basically it would be sufficient to implement this as a static method:
class IntegerAdder implements Adder<Integer> {
public static Integer add (Integer ... arguments) { }
}
But because Java does not allow static interface methods it has to be implemented in a non static way. The result is, that when ever an IntegerAdder is required one has to create an instance.
IntegerAdder integer_adder = new IntegerAdder();
Integer a = 1;
Integer b = 2;
Integer c = integer_adder.add (1, 2);
I fear this might be slower than the version without the instance creation:
Integer a = 1;
Integer b = 2;
Integer c = IntegerAdder.add (1, 2);
But how much slower is it in reality? Is it possible for the Java compiler to optimize the first version in that way that it performs as fast as the second one? And is this actually done?
You can create an instance of IntegerAdder once and reuse it, it is thread safe. Also pay attention that Integer ... arguments leads to 1) using objects instead of primitive ints 2) creating an array to pass parameters. Both things should be avoided if performance is concern

What is the best way to implement constants in Java? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Closed 5 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
I've seen examples like this:
public class MaxSeconds {
public static final int MAX_SECONDS = 25;
}
and supposed that I could have a Constants class to wrap constants in, declaring them static final. I know practically no Java at all and am wondering if this is the best way to create constants.
That is perfectly acceptable, probably even the standard.
(public/private) static final TYPE NAME = VALUE;
where TYPE is the type, NAME is the name in all caps with underscores for spaces, and VALUE is the constant value;
I highly recommend NOT putting your constants in their own classes or interfaces.
As a side note: Variables that are declared final and are mutable can still be changed; however, the variable can never point at a different object.
For example:
public static final Point ORIGIN = new Point(0,0);
public static void main(String[] args){
ORIGIN.x = 3;
}
That is legal and ORIGIN would then be a point at (3, 0).
I would highly advise against having a single constants class. It may seem a good idea at the time, but when developers refuse to document constants and the class grows to encompass upwards of 500 constants which are all not related to each other at all (being related to entirely different aspects of the application), this generally turns into the constants file being completely unreadable. Instead:
If you have access to Java 5+, use enums to define your specific constants for an application area. All parts of the application area should refer to enums, not constant values, for these constants. You may declare an enum similar to how you declare a class. Enums are perhaps the most (and, arguably, only) useful feature of Java 5+.
If you have constants that are only valid to a particular class or one of its subclasses, declare them as either protected or public and place them on the top class in the hierarchy. This way, the subclasses can access these constant values (and if other classes access them via public, the constants aren't only valid to a particular class...which means that the external classes using this constant may be too tightly coupled to the class containing the constant)
If you have an interface with behavior defined, but returned values or argument values should be particular, it is perfectly acceptible to define constants on that interface so that other implementors will have access to them. However, avoid creating an interface just to hold constants: it can become just as bad as a class created just to hold constants.
It is a BAD PRACTICE to use interfaces just to hold constants (named constant interface pattern by Josh Bloch). Here's what Josh advises:
If the constants are strongly tied to
an existing class or interface, you
should add them to the class or
interface. For example, all of the
boxed numerical primitive classes,
such as Integer and Double, export
MIN_VALUE and MAX_VALUE constants. If
the constants are best viewed as
members of an enumerated type, you
should export them with an enum
type. Otherwise, you should export the
constants with a noninstantiable
utility class.
Example:
// Constant utility class
package com.effectivejava.science;
public class PhysicalConstants {
private PhysicalConstants() { } // Prevents instantiation
public static final double AVOGADROS_NUMBER = 6.02214199e23;
public static final double BOLTZMANN_CONSTANT = 1.3806503e-23;
public static final double ELECTRON_MASS = 9.10938188e-31;
}
About the naming convention:
By convention, such fields have names
consisting of capital letters, with
words separated by underscores. It is
critical that these fields contain
either primitive values or references
to immutable objects.
In Effective Java (2nd edition), it's recommended that you use enums instead of static ints for constants.
There's a good writeup on enums in Java here:
http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html
Note that at the end of that article the question posed is:
So when should you use enums?
With an answer of:
Any time you need a fixed set of constants
Just avoid using an interface:
public interface MyConstants {
String CONSTANT_ONE = "foo";
}
public class NeddsConstant implements MyConstants {
}
It is tempting, but violates encapsulation and blurs the distinction of class definitions.
I use following approach:
public final class Constants {
public final class File {
public static final int MIN_ROWS = 1;
public static final int MAX_ROWS = 1000;
private File() {}
}
public final class DB {
public static final String name = "oups";
public final class Connection {
public static final String URL = "jdbc:tra-ta-ta";
public static final String USER = "testUser";
public static final String PASSWORD = "testPassword";
private Connection() {}
}
private DB() {}
}
private Constants() {}
}
Than, for example, I use Constants.DB.Connection.URL to get constant.
It looks more "object oriently" as for me.
Creating static final constants in a separate class can get you into trouble. The Java compiler will actually optimize this and place the actual value of the constant into any class that references it.
If you later change the 'Constants' class and you don't do a hard re-compile on other classes that reference that class, you will wind up with a combination of old and new values being used.
Instead of thinking of these as constants, think of them as configuration parameters and create a class to manage them. Have the values be non-final, and even consider using getters. In the future, as you determine that some of these parameters actually should be configurable by the user or administrator, it will be much easier to do.
The number one mistake you can make is creating a globally accessible class called with a generic name, like Constants. This simply gets littered with garbage and you lose all ability to figure out what portion of your system uses these constants.
Instead, constants should go into the class which "owns" them. Do you have a constant called TIMEOUT? It should probably go into your Communications() or Connection() class. MAX_BAD_LOGINS_PER_HOUR? Goes into User(). And so on and so forth.
The other possible use is Java .properties files when "constants" can be defined at run-time, but not easily user changeable. You can package these up in your .jars and reference them with the Class resourceLoader.
That's the right way to go.
Generally constants are not kept in separate "Constants" classes because they're not discoverable. If the constant is relevant to the current class, keeping them there helps the next developer.
What about an enumeration?
I prefer to use getters rather than constants. Those getters might return constant values, e.g. public int getMaxConnections() {return 10;}, but anything that needs the constant will go through a getter.
One benefit is that if your program outgrows the constant--you find that it needs to be configurable--you can just change how the getter returns the constant.
The other benefit is that in order to modify the constant you don't have to recompile everything that uses it. When you reference a static final field, the value of that constant is compiled into any bytecode that references it.
I agree that using an interface is not the way to go. Avoiding this pattern even has its own item (#18) in Bloch's Effective Java.
An argument Bloch makes against the constant interface pattern is that use of constants is an implementation detail, but implementing an interface to use them exposes that implementation detail in your exported API.
The public|private static final TYPE NAME = VALUE; pattern is a good way of declaring a constant. Personally, I think it's better to avoid making a separate class to house all of your constants, but I've never seen a reason not to do this, other than personal preference and style.
If your constants can be well-modeled as an enumeration, consider the enum structure available in 1.5 or later.
If you're using a version earlier than 1.5, you can still pull off typesafe enumerations by using normal Java classes. (See this site for more on that).
Based on the comments above I think this is a good approach to change the old-fashioned global constant class (having public static final variables) to its enum-like equivalent in a way like this:
public class Constants {
private Constants() {
throw new AssertionError();
}
public interface ConstantType {}
public enum StringConstant implements ConstantType {
DB_HOST("localhost");
// other String constants come here
private String value;
private StringConstant(String value) {
this.value = value;
}
public String value() {
return value;
}
}
public enum IntConstant implements ConstantType {
DB_PORT(3128),
MAX_PAGE_SIZE(100);
// other int constants come here
private int value;
private IntConstant(int value) {
this.value = value;
}
public int value() {
return value;
}
}
public enum SimpleConstant implements ConstantType {
STATE_INIT,
STATE_START,
STATE_END;
}
}
So then I can refer them to like:
Constants.StringConstant.DB_HOST
A good object oriented design should not need many publicly available constants. Most constants should be encapsulated in the class that needs them to do its job.
There is a certain amount of opinion to answer this. To start with, constants in java are generally declared to be public, static and final. Below are the reasons:
public, so that they are accessible from everywhere
static, so that they can be accessed without any instance. Since they are constants it
makes little sense to duplicate them for every object.
final, since they should not be allowed to change
I would never use an interface for a CONSTANTS accessor/object simply because interfaces are generally expected to be implemented. Wouldn't this look funny:
String myConstant = IMyInterface.CONSTANTX;
Instead I would choose between a few different ways, based on some small trade-offs, and so it depends on what you need:
1. Use a regular enum with a default/private constructor. Most people would define
constants this way, IMHO.
- drawback: cannot effectively Javadoc each constant member
- advantage: var members are implicitly public, static, and final
- advantage: type-safe
- provides "a limited constructor" in a special way that only takes args which match
predefined 'public static final' keys, thus limiting what you can pass to the
constructor
2. Use a altered enum WITHOUT a constructor, having all variables defined with
prefixed 'public static final' .
- looks funny just having a floating semi-colon in the code
- advantage: you can JavaDoc each variable with an explanation
- drawback: you still have to put explicit 'public static final' before each variable
- drawback: not type-safe
- no 'limited constructor'
3. Use a Class with a private constructor:
- advantage: you can JavaDoc each variable with an explanation
- drawback: you have to put explicit 'public static final' before each variable
- you have the option of having a constructor to create an instance
of the class if you want to provide additional functions related
to your constants
(or just keep the constructor private)
- drawback: not type-safe
4. Using interface:
- advantage: you can JavaDoc each variable with an explanation
- advantage: var members are implicitly 'public static final'
- you are able to define default interface methods if you want to provide additional
functions related to your constants (only if you implement the interface)
- drawback: not type-safe
What is the best way to implement constants in Java?
One approach that we should really avoid : using interfaces to define constants.
Creating a interface specifically to declare constants is really the worst thing : it defeats the reason why interfaces were designed : defining method(s) contract.
Even if an interface already exists to address a specific need, declaring the constants in them make really not sense as constants should not make part of the API and the contract provided to client classes.
To simplify, we have broadly 4 valid approaches.
With static final String/Integer field :
1) using a class that declares constants inside but not only.
1 variant) creating a class dedicated to only declare constants.
With Java 5 enum :
2) declaring the enum in a related purpose class (so as a nested class).
2 variant) creating the enum as a standalone class (so defined in its own class file).
TLDR : Which is the best way and where locate the constants ?
In most of cases, the enum way is probably finer than the static final String/Integer way and personally I think that the static final String/Integer way should be used only if we have good reasons to not use enums.
And about where we should declare the constant values, the idea is to search whether there is a single existing class that owns a specific and strong functional cohesion with constant values. If we find such a class, we should use it as the constants holder. Otherwise, the constant should be associated to no one particular class.
static final String/ static final Integer versus enum
Enums usage is really a way to strongly considered.
Enums have a great advantage over String or Integer constant field.
They set a stronger compilation constraint.
If you define a method that takes the enum as parameter, you can only pass a enum value defined in the enum class(or null).
With String and Integer you can substitute them with any values of compatible type and the compilation will be fine even if the value is not a defined constant in the static final String/ static final Integer fields.
For example, below two constants defined in a class as static final String fields :
public class MyClass{
public static final String ONE_CONSTANT = "value";
public static final String ANOTHER_CONSTANT = "other value";
. . .
}
Here a method that expects to have one of these constants as parameter :
public void process(String constantExpected){
...
}
You can invoke it in this way :
process(MyClass.ONE_CONSTANT);
or
process(MyClass.ANOTHER_CONSTANT);
But no compilation constraint prevents you from invoking it in this way :
process("a not defined constant value");
You would have the error only at runtime and only if you do at a time a check on the transmitted value.
With enum, checks are not required as the client could only pass a enum value in a enum parameter.
For example, here two values defined in a enum class (so constant out of the box):
public enum MyEnum {
ONE_CONSTANT("value"), ANOTHER_CONSTANT(" another value");
private String value;
MyEnum(String value) {
this.value = value;
}
...
}
Here a method that expects to have one of these enum values as parameter :
public void process(MyEnum myEnum){
...
}
You can invoke it in this way :
process(MyEnum.ONE_CONSTANT);
or
process(MyEnum.ANOTHER_CONSTANT);
But the compilation will never allow you from invoking it in this way :
process("a not defined constant value");
Where should we declare the constants ?
If your application contains a single existing class that owns a specific and strong functional cohesion with the constant values, the 1) and the 2) appear more intuitive.
Generally, it eases the use of the constants if these are declared in the main class that manipulates them or that has a name very natural to guess that we will find it inside.
For example in the JDK library, the exponential and pi constant values are declared in a class that declare not only constant declarations (java.lang.Math).
public final class Math {
...
public static final double E = 2.7182818284590452354;
public static final double PI = 3.14159265358979323846;
...
}
The clients using mathematics functions rely often on the Math class.
So, they may find constants easily enough and can also remember where E and PI are defined in a very natural way.
If your application doesn't contain an existing class that has a very specific and strong functional cohesion with the constant values, the 1 variant) and the 2 variant) ways appear more intuitive.
Generally, it doesn't ease the use of the constants if these are declared in one class that manipulates them while we have also 3 or 4 other classes that manipulate them as much as and no one of these classes seems be more natural than others to host constant values.
Here, defining a custom class to hold only constant values makes sense.
For example in the JDK library, the java.util.concurrent.TimeUnit enum is not declared in a specific class as there is not really one and only one JDK specific class that appear as the most intuitive to hold it :
public enum TimeUnit {
NANOSECONDS {
.....
},
MICROSECONDS {
.....
},
MILLISECONDS {
.....
},
SECONDS {
.....
},
.....
}
Many classes declared in java.util.concurrent use them :
BlockingQueue, ArrayBlockingQueue<E>, CompletableFuture, ExecutorService , ... and really no one of them seems more appropriate to hold the enum.
A Constant, of any type, can be declared by creating an immutable property that within a class (that is a member variable with the final modifier). Typically the static and public modifiers are also provided.
public class OfficePrinter {
public static final String STATE = "Ready";
}
There are numerous applications where a constant's value indicates a selection from an n-tuple (e.g. enumeration) of choices. In our example, we can choose to define an Enumerated Type that will restrict the possible assigned values (i.e. improved type-safety):
public class OfficePrinter {
public enum PrinterState { Ready, PCLoadLetter, OutOfToner, Offline };
public static final PrinterState STATE = PrinterState.Ready;
}
A single, generic constants class is a bad idea. Constants should be grouped together with the class they're most logically related to.
Rather than using variables of any kind (especially enums), I would suggest that you use methods. Create a method with the same name as the variable and have it return the value you assigned to the variable. Now delete the variable and replace all references to it with calls to the method you just created. If you feel that the constant is generic enough that you shouldn't have to create an instance of the class just to use it, then make the constant method a class method.
FWIW, a timeout in seconds value should probably be a configuration setting (read in from a properties file or through injection as in Spring) and not a constant.
What is the difference
1.
public interface MyGlobalConstants {
public static final int TIMEOUT_IN_SECS = 25;
}
2.
public class MyGlobalConstants {
private MyGlobalConstants () {} // Prevents instantiation
public static final int TIMEOUT_IN_SECS = 25;
}
and using
MyGlobalConstants.TIMEOUT_IN_SECS wherever we need this constant. I think both are same.
I wouldn't call the class the same (aside from casing) as the constant ... I would have at a minimum one class of "Settings", or "Values", or "Constants", where all the constants would live. If I have a large number of them, I'd group them up in logical constant classes (UserSettings, AppSettings, etc.)
To take it a step further, you can place globally used constants in an interface so they can be used system wide. E.g.
public interface MyGlobalConstants {
public static final int TIMEOUT_IN_SECS = 25;
}
But don't then implement it. Just refer to them directly in code via the fully qualified classname.
For Constants, Enum is a better choice IMHO. Here is an example
public class myClass {
public enum myEnum {
Option1("String1", 2),
Option2("String2", 2)
;
String str;
int i;
myEnum(String str1, int i1) { this.str = str1 ; this.i1 = i }
}
One of the way I do it is by creating a 'Global' class with the constant values and do a static import in the classes that need access to the constant.
static final is my preference, I'd only use an enum if the item was indeed enumerable.
I use static final to declare constants and go with the ALL_CAPS naming notation. I have seen quite a few real life instances where all constants are bunched together into an interface. A few posts have rightly called that a bad practice, primarily because that's not what an interface is for. An interface should enforce a contract and should not be a place to put unrelated constants in. Putting it together into a class that cannot be instantiated (through a private constructor) too is fine if the constant semantics don't belong to a specific class(es). I always put a constant in the class that it's most related to, because that makes sense and is also easily maintainable.
Enums are a good choice to represent a range of values, but if you are storing standalone constants with an emphasis on the absolute value (eg. TIMEOUT = 100 ms) you can just go for the static final approach.
I agree with what most are saying, it is best to use enums when dealing with a collection of constants. However, if you are programming in Android there is a better solution: IntDef Annotation.
#Retention(SOURCE)
#IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST,NAVIGATION_MODE_TABS})
public #interface NavigationMode {}
public static final int NAVIGATION_MODE_STANDARD = 0;
public static final int NAVIGATION_MODE_LIST = 1;
public static final int NAVIGATION_MODE_TABS = 2;
...
public abstract void setNavigationMode(#NavigationMode int mode);
#NavigationMode
public abstract int getNavigationMode();
IntDef annotation is superior to enums in one simple way, it takes significantly less space as it is simply a compile-time marker. It is not a class, nor does it have the automatic string-conversion property.
It is BAD habit and terribly
ANNOYING practice to quote Joshua Bloch without understanding the basic ground-zero fundamentalism.
I have not read anything Joshua Bloch, so either
he is a terrible programmer
or the people so far whom I find quoting him (Joshua is the name of a boy I presume) are simply using his material as religious scripts to justify their software religious indulgences.
As in Bible fundamentalism all the biblical laws can be summed up by
Love the Fundamental Identity with all your heart and all your mind
Love your neighbour as yourself
and so similarly software engineering fundamentalism can be summed up by
devote yourself to the ground-zero fundamentals with all your programming might and mind
and devote towards the excellence of your fellow-programmers as you would for yourself.
Also, among biblical fundamentalist circles a strong and reasonable corollary is drawn
First love yourself. Because if you don't love yourself much, then the concept "love your neighbour as yourself" doesn't carry much weight, since "how much you love yourself" is the datum line above which you would love others.
Similarly, if you do not respect yourself as a programmer and just accept the pronouncements and prophecies of some programming guru-nath WITHOUT questioning the fundamentals, your quotations and reliance on Joshua Bloch (and the like) is meaningless. And therefore, you would actually have no respect for your fellow-programmers.
The fundamental laws of software programming
laziness is the virtue of a good programmer
you are to make your programming life as easy, as lazy and therefore as effective as possible
you are to make the consequences and entrails of your programming as easy, as lazy and therefore as effective as possible for your neigbour-programmers who work with you and pick up your programming entrails.
Interface-pattern constants is a bad habit ???
Under what laws of fundamentally effective and responsible programming does this religious edict fall into ?
Just read the wikipedia article on interface-pattern constants (https://en.wikipedia.org/wiki/Constant_interface), and the silly excuses it states against interface-pattern constants.
Whatif-No IDE? Who on earth as a software programmer would not use an IDE? Most of us are programmers who prefer not to have to prove having macho aescetic survivalisticism thro avoiding the use of an IDE.
Also - wait a second proponents of micro-functional programming as a means of not needing an IDE. Wait till you read my explanation on data-model normalization.
Pollutes the namespace with variables not used within the current scope? It could be proponents of this opinion
are not aware of, and the need for, data-model normalization
Using interfaces for enforcing constants is an abuse of interfaces. Proponents of such have a bad habit of
not seeing that "constants" must be treated as contract. And interfaces are used for enforcing or projecting compliance to a contract.
It is difficult if not impossible to convert interfaces into implemented classes in the future. Hah .... hmmm ... ???
Why would you want to engage in such pattern of programming as your persistent livelihood? IOW, why devote yourself to such an AMBIVALENT and bad programming habit ?
Whatever the excuses, there is NO VALID EXCUSE when it comes to FUNDAMENTALLY EFFECTIVE software engineering to delegitimize or generally discourage the use of interface constants.
It doesn't matter what the original intents and mental states of the founding fathers who crafted the United States Constitution were. We could debate the original intents of the founding fathers but all I care is the written statements of the US Constitution. And it is the responsibility of every US citizen to exploit the written literary-fundamentalism, not the unwritten founding-intents, of the US Constitution.
Similarly, I do not care what the "original" intents of the founders of the Java platform and programming language had for the interface. What I care are the effective features the Java specification provides, and I intend to exploit those features to the fullest to help me fulfill the fundamental laws of responsible software programming. I don't care if I am perceived to "violate the intention for interfaces". I don't care what Gosling or someone Bloch says about the "proper way to use Java", unless what they say does not violate my need to EFFECTIVE fulfilling fundamentals.
The Fundamental is Data-Model Normalization
It doesn't matter how your data-model is hosted or transmitted. Whether you use interfaces or enums or whatevernots, relational or no-SQL, if you don't understand the need and process of data-model normalization.
We must first define and normalize the data-model of a set of processes. And when we have a coherent data-model, ONLY then can we use the process flow of its components to define the functional behaviour and process blocks a field or realm of applications. And only then can we define the API of each functional process.
Even the facets of data normalization as proposed by EF Codd is now severely challenged and severely-challenged. e.g. his statement on 1NF has been criticized as ambiguous, misaligned and over-simplified, as is the rest of his statements especially in the advent of modern data services, repo-technology and transmission. IMO, the EF Codd statements should be completely ditched and new set of more mathematically plausible statements be designed.
A glaring flaw of EF Codd's and the cause of its misalignment to effective human comprehension is his belief that humanly perceivable multi-dimensional, mutable-dimension data can be efficiently perceived thro a set of piecemeal 2-dimensional mappings.
The Fundamentals of Data Normalization
What EF Codd failed to express.
Within each coherent data-model, these are the sequential graduated order of data-model coherence to achieve.
The Unity and Identity of data instances.
design the granularity of each data component, whereby their granularity is at a level where each instance of a component can be uniquely identified and retrieved.
absence of instance aliasing. i.e., no means exist whereby an identification produces more than one instance of a component.
Absence of instance crosstalk. There does not exist the necessity to use one or more other instances of a component to contribute to identifying an instance of a component.
The unity and identity of data components/dimensions.
Presence of component de-aliasing. There must exist one definition whereby a component/dimension can be uniquely identified. Which is the primary definition of a component;
where the primary definition will not result in exposing sub-dimensions or member-components that are not part of an intended component;
Unique means of component dealiasing. There must exist one, and only one, such component de-aliasing definition for a component.
There exists one, and only one, definition interface or contract to identify a parent component in a hierarchical relationship of components.
Absence of component crosstalk. There does not exist the necessity to use a member of another component to contribute to the definitive identification of a component.
In such a parent-child relationship, the identifying definition of a parent must not depend on part of the set of member components of a child. A member component of a parent's identity must be the complete child identity without resorting to referencing any or all of the children of a child.
Preempt bi-modal or multi-modal appearances of a data-model.
When there exists two candidate definitions of a component, it is an obvious sign that there exists two different data-models being mixed up as one. That means there is incoherence at the data-model level, or the field level.
A field of applications must use one and only one data-model, coherently.
Detect and identify component mutation. Unless you have performed statistical component analysis of huge data, you probably do not see, or see the need to treat, component mutation.
A data-model may have its some of its components mutate cyclically or gradually.
The mode may be member-rotation or transposition-rotation.
Member-rotation mutation could be distinct swapping of child components between components. Or where completely new components would have to be defined.
Transpositional mutation would manifest as a dimensional-member mutating into an attribute, vice versa.
Each mutation cycle must be identified as a distinct data-modal.
Versionize each mutation. Such that you can pull out a previous version of the data model, when perhaps the need arise to treat an 8 year old mutation of the data model.
In a field or grid of inter-servicing component-applications, there must be one and only one coherent data-model or exists a means for a data-model/version to identify itself.
Are we still asking if we could use Interface Constants? Really ?
There are data-normalization issues at stake more consequential than this mundane question. IF you don't solve those issues, the confusion that you think interface constants cause is comparatively nothing. Zilch.
From the data-model normalization then you determine the components as variables, as properties, as contract interface constants.
Then you determine which goes into value injection, property configuration placeholding, interfaces, final strings, etc.
If you have to use the excuse of needing to locate a component easier to dictate against interface constants, it means you are in the bad habit of not practicing data-model normalization.
Perhaps you wish to compile the data-model into a vcs release. That you can pull out a distinctly identifiable version of a data-model.
Values defined in interfaces are completely assured to be non-mutable. And shareable. Why load a set of final strings into your class from another class when all you need is that set of constants ??
So why not this to publish a data-model contract? I mean if you can manage and normalize it coherently, why not? ...
public interface CustomerService {
public interface Label{
char AssignmentCharacter = ':';
public interface Address{
String Street = "Street";
String Unit= "Unit/Suite";
String Municipal = "City";
String County = "County";
String Provincial = "State";
String PostalCode = "Zip"
}
public interface Person {
public interface NameParts{
String Given = "First/Given name"
String Auxiliary = "Middle initial"
String Family = "Last name"
}
}
}
}
Now I can reference my apps' contracted labels in a way such as
CustomerService.Label.Address.Street
CustomerService.Label.Person.NameParts.Family
This confuses the contents of the jar file? As a Java programmer I don't care about the structure of the jar.
This presents complexity to osgi-motivated runtime swapping ? Osgi is an extremely efficient means to allow programmers to continue in their bad habits. There are better alternatives than osgi.
Or why not this? There is no leakage of of the private Constants into published contract. All private constants should be grouped into a private interface named "Constants", because I don't want to have to search for constants and I am too lazy to repeatedly type "private final String".
public class PurchaseRequest {
private interface Constants{
String INTERESTINGName = "Interesting Name";
String OFFICIALLanguage = "Official Language"
int MAXNames = 9;
}
}
Perhaps even this:
public interface PurchaseOrderConstants {
public interface Properties{
default String InterestingName(){
return something();
}
String OFFICIALLanguage = "Official Language"
int MAXNames = 9;
}
}
The only issue with interface constants worth considering is when the interface is implemented.
This is not the "original intention" of interfaces? Like I would care about the "original intention" of the founding fathers in crafting the US Constitution, rather than how the Supreme Court would interpret the written letters of the US Constitution ???
After all, I live in the land of the free, the wild and home of the brave. Be brave, be free, be wild - use the interface. If my fellow-programmers refuse to use efficient and lazy means of programming, am I obliged by the golden rule to lessen my programming efficiency to align with theirs? Perhaps I should, but that is not an ideal situation.

Struct like objects in Java

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??? :)

Categories