JavaBeans and introspection - messed up on boolean and indexed properties? - java

A former colleague of mine started a discussion half an hour ago about JavaBeans, and why they didn't quite work the way he wants in JSF. The particular case is about boolean properties.
1. For a boolean property named isUrl Eclipse generates this
private boolean isUrl;
public boolean isUrl() {..}
public boolean setUrl(boolean url) {..}
But this does not work in JSF. He made it work by adding public boolean getIsUrl() The implementation might be buggy, so let's make sure who's right, by using the introspection API.:
BeanInfo info = Introspector.getBeanInfo(ClassTest.class);
for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
System.out.println(pd.getName() + ": " + pd.getReadMethod() +
" : " + pd.getWriteMethod());
}
For the above code, this prints both methods - i.e. Eclipse is right, JSF is wrong. But that sounded suspicious to me, since the specification doesn't mention anything about the double "is".
But while looking through the spec, I saw something I've never used - the so called indexed properties. You can have private String[] bar and then public String getBar(int idx). So:
2. I tried that with the Introspector, and it didn't find a read method for bar. The result from the above code was: bar: null : null. So I came to think - now the introspector does not follow the spec. Perhaps it didn't follow it in the previous case, and ultimately, JSF is right. In fact, indexed properties can make so that there are two read methods for a given property. And that's not possible with the PropertyDescriptor class of the introspection API.
What does this lead us to - we have a possibly broken API that does not conform to the spec. Which leads to other implementations of the spec (JSF uses a custom one obviously). Which leads to further misunderstandings and confusions.
A sidenote for something that bothered me - in the JavaBeans spec they call the naming conventions for the methods "design patterns". This sounds wrong to me.
So, now onto the questions:
is the JavaBeans spec clear
is the introspection API correct
is a new JavaBeans specification needed, at least to clarify the behaviour of booleans (that's subjective to an extent)
Update. it appears the JSF usage is bean.isUrl rathern than bean.url. Which makes perfects sense not to work with isUrl() accessor.
P.S. JDK 1.6.0_20, JSF 1.2, MyFaces

Java Bean Properties are defined by methods, not by fields. For this reason the PropertyDescriptor class has getReadMethod() and getWriteMethod() methods, but no getField() methods.
Personally, I think your colleague is using a bad practice.
a) is is a verb. Fields should not be named after verbs.
b) while it's not required, good practice is to name the field like the property, which lets you write code like this:
PropertyDescriptor pd; // let's assume this is set
Method referenceMethod = pd.getReadMethod() == null
// at least one of these is not null
? pd.getWriteMethod() : pd.getReadMethod();
Field underLyingField = referenceMethod
.getDeclaringClass()
.getDeclaredField(pd.getName());
While this code is not standardized, it is following conventions and can come in very handy. If you don't follow conventions like this, you have no way of associating a field with a property (which is intentional, I know).
e.g. I use code like the above to check if the field has annotations
About indexed properties:
You can use the index syntax on array or list (or map) properties, but only if they are defined as standard bean properties.
So if you have a property like this:
private String[] bar;
public String[] getBar(){
return bar;
}
public void setBar(String[] bar){
this.bar = bar;
}
or like this:
private List<String> bar;
public List<String> getBar(){
return bar;
}
public void setBar(List<String> bar){
this.bar = bar;
}
you can access the first member with the expression ${bar[0]}
And with a map property like this:
private Map<String, String> bar;
public Map<String, String> getBar(){
return bar;
}
public void setBar(Map<String, String> bar){
this.bar = bar;
}
You can access the value mapped to "baz" like this ${bar['baz']}.
This functionality builds on top of standard beans functionality, so it requires regular getters / setters.

As mentioned by #Peter Lawrey, the name of the field is irrelevant as far as JavaBeans is concerned. It needn't even exist, or you can give it a silly name such as prefixing with m_.
You didn't provide a suitable read or write methods for the bar property as a whole, so these are not going to show up. You can't synthesize a Method to an existing class at runtime. I believe indexed properties were a late edition, even though there isn't an #since apparent, so they aren't used by java.beans interfaces.
I don't have the JSF spec (and it'll be behind the jcp.org lawyer wall), so don't know what it claims. It may specify something different to the JavaBeans spec [probable], or you may be using an implementation with bugs [I guess also probable].
"Design pattern" is just a phrase. As in a pattern that occurs in our design. It's not Design Pattern as in GoF.

Related

Is there a shorthand to copy an object within a constructor?

Is there some way to achieve this = that in a constructor? that is an object that I want to copy (and thus is an object of the same class as this, this being the object reference).
class Foo {
private final Bar bar;
public Foo() {
Foo that = DaggerFactory.create().getFoo();
// this = that; but it's not working!?
}
#Inject
public Foo(Bar bar) {
this.bar = bar;
}
// Other methods
}
I've seen examples of copy constructors where they copied the members one by one i.e. this.bar = that.bar. This is my last option as I've got a handful of members in the class, and I don't want to unnecessarily "clutter" my code.
P.S. I do want to instantiate the objects through the empty constructor as that's how AWS Lambda works (where I will be deploying this). So far I haven't found any way where I could get Lambda to use Dagger provided objects. If there is a better approach with respect to Lambda / Dagger that would also be great!
There is no clever (shortcut / shorthand) way to write a copy constructor in Java. At the source code level you must assign the fields one at a time.
Normally, I would just "bite the bullet" and write the code. But there are a couple of other alternatives:
Your IDE may have a way to generate a copy constructor. (Eclipse doesn't, but apparently you can generate a regular constructor for all field, and then do some clever search-replace stuff on the generated code; see Eclipse generate copy constructor)
You could conceivably write some reusable code that copies fields from one object to another using reflection. This is rather inefficient, but it might be acceptable if you have to deal with classes that have a ridiculous number of fields.
You could use the clone() mechanism instead.

Is it possible to set object properties dynamically in Java (without reflection)?

Say I have the following class:
class Foo
{
public String bar;
public String baz;
}
And I have the following code, in another class:
Foo foo = new Foo();
String[] properties = {"bar", "baz"};
String[] values = {"barValue", "bazValue"};
Is it possible to iterate over the properties array and use that to set the values of Foo? E.g something like:
for (int i = 0; i < properties.length; i++)
{
foo[ properties[i] ] = values[i];
}
Is something like the above possible?
Is something like the above possible?
No.
With the properties as you have defined them, your only choices are:
writing or generating Java code (or bytecodes) to refer to the fields a foo.bar or foo.baz, or
use reflection.
If you want dynamic properties, use a Map object; e.g. a HashMap<String, String>.
As to your illustrative example, that won't / can't work because:
regular object fields cannot be indexed like an array, and
unlike C++, Python and other languages, Java doesn't support ad-hoc overloading of any of the core language constructs (apart from methods).
Java is not a dynamic language that supports this kind of thing. You need to learn to live with what it can offer you ... or use a different language.
You commented thus:
Reflection is supposed to be bad for performance.
Well yes, but it is relative. Accessing or updating a field reflectively is likely to be 10 to 100 times slower than accessing/updating it using normal Java code. However, if you are only doing this occasionally, the performance overhead may not be relevant. If it does turn out to be an issue, then your options include hand-writing, or generating the code. For example:
public class Foo
{
public String bar;
public String baz;
public void setNamedProperty(String name, String value) {
switch (name) {
case "bar":
bar = value;
break;
case "baz":
baz = value;
break;
default:
throw new IllegalArgumentException("Unknown property name");
}
}
}
For what it is worth, that code is going to be about as time efficient as setting a dynamic property in a language that supports dynamic properties. (And I suspect it will be more space efficient, given that dynamic properties are typically implemented using native coded hash tables.)
You can use Introspection, and it is much better a way when you face Java Beans.
Cons are:
It will call getter/setters if they are present, or will access fields directly if there are no getter/setters and fields are public.
You can iterate over properties, because it gives you an array of PropertyDescriptors.
It support BeanInfo classes,
so you can configure your bean properties
define accessor/mutators with different naming convention (not getter or setter)
You can use libraries like Apache Commons BeanUtils or Spring BeanWrapper API.
For more information look at java.beans.Introspector javadocs.
By the way as far as I know Interospection is built upon reflection, so it uses reflection itself.

Compiletime validation of enum parameters

There is a constructor with three parameters of type enum:
public SomeClass(EnumType1 enum1,EnumType2 enum2, EnumType3 enum3)
{...}
The three parameters of type enum are not allowd to be combined with all possible values:
Example:
EnumType1.VALUE_ONE, EnumType2.VALUE_SIX, EnumType3.VALUE_TWENTY is a valid combination.
But the following combination is not valid:
EnumType1.VALUE_TWO, EnumType2.VALUE_SIX, EnumType3.VALUE_FIFTEEN
Each of the EnumTypes knows with which values it is allowed to be combined:
EnumType1 and the two others implement a isAllowedWith() method to check that as follows:
public enum EnumType1 {
VALUE_ONE,VALUE_TWO,...;
public boolean isAllowedWith(final EnumType2 type) {
switch (this) {
case VALUE_ONE:
return type.equals(Type.VALUE_THREE);
case VALUE_TWO:
return true;
case VALUE_THREE:
return type.equals(Type.VALUE_EIGHT);
...
}
}
I need to run that check at compile time because it is of extreme importance in my project that the combinations are ALWAYS correct at runtime.
I wonder if there is a possibility to run that check with user defined annotations?
Every idea is appreciated :)
The posts above don't bring a solution for compile-time check, here's mine:
Why not use concept of nested Enum.
You would have EnumType1 containing its own values + a nested EnumType2 and this one a nested EnumType3.
You could organize the whole with your useful combination.
You could end up with 3 classes (EnumType1,2 and 3) and each one of each concerned value containing the others with the allowed associated values.
And your call would look like that (with assuming you want EnumType1.VALUE_ONE associated with EnumType2.VALUE_FIFTEEN) :
EnumType1.VALUE_ONE.VALUE_FIFTEEN //second value corresponding to EnumType2
Thus, you could have also: EnumType3.VALUE_SIX.VALUE_ONE (where SIX is known by type3 and ONE by type1).
Your call would be change to something like:
public SomeClass(EnumType1 enumType)
=> sample:
SomeClass(EnumType1.VALUE_ONE.VALUE_SIX.VALUE_TWENTY) //being a valid combination as said
To better clarify it, check at this post: Using nested enum types in Java
So the simplest way to do this is to 1) Define the documentation to explain valid combinations and
2) add the checks in the constructor
If a constructor throws an Exception than that is the responsibility of the invoker. Basically you would do something like this:
public MyClass(enum foo, enum bar, enum baz)
{
if(!validateCombination(foo,bar,baz))
{
throw new IllegalStateException("Contract violated");
}
}
private boolean validateCombination(enum foo, enum bar, enum baz)
{
//validation logic
}
Now this part is absolutely critical. Mark the class a final, it is possible that a partially constructed object can be recovered and abused to break your application. With a class marked as final a malicious program cannot extend the partially constructed object and wreak havoc.
One alternative idea is to write some automated tests to catch this, and hook them into your build process as a compulsory step before packaging/deploying your app.
If you think about what you're trying to catch here, it's code which is legal but wrong. While you could catch that during the compilation phase, this is exactly what tests are meant for.
This would fit your requirement of not being able to build any code with an illegal combination, because the build would still fail. And arguably it would be easier for other developers to understand than writing your own annotation processor...
The only way I know is to work with annotations.
Here is what I do I mean.
Now your constructor accepts 3 parameters:
public SomeClass(EnumType1 enum1,EnumType2 enum2, EnumType3 enum3){}
so you are calling it as following:
SomeClass obj = new SomeClass(EnumTupe1.VALUE1, EnumTupe2.VALUE2, EnumTupe1.VALUE3)
Change the constructor to be private. Create public constructor that accept 1 parameter of any type you want. It may be just a fake parameter.
public SomeClass(Placeholder p)
Now you have to require to call this constructor while each argument is annotated with special annotation. Let's call it TypeAnnotation:
SomeClass obj = new SomeClass(TypeAnnotation(
type1=EnumType1.VALUE1,
type2=EnumTupe2.VALUE2,
type3=EnumTupe1.VALUE3)
p3);
The call is more verbose but this is what we have to pay for compile time validation.
Now, how to define the annotation?
#Documented
#Retention({RetentionPolicy.RUNTIME, RetentionPolicy.SOURCE})
#Target(PARAMETER)
#interface TypeAnnotation {
EnumType1 type1();
EnumType2 type3();
EnumType3 type3();
}
Please pay attention that target is PARAMETER and retention values are RUNTIME and SOURCE.
RUNTIME allows reading this annotation at runtime, while SOURCE allows creating annotation processor that can validate the parameters at runtime.
Now the public constructor will call the 3-parameters private construcor:
public SomeClass(Placeholder p) {
this(readAnnotation(EnumType1.class), readAnnotation(EnumType2.class), readAnnotation(EnumType3.class), )
}
I am not implementing readAnnotation() here: it should be static method that takes stack trace, goes 3 elements back (to caller of the public costructor) and parses annotation TypeAnnotation.
Now is the most interesting part. You have to implement annotation processor.
Take a look here for instructions and here for an example of annotation processor.
You will have to add usage of this annotation processor to your build script and (optionally) to your IDE. In this case you will get real compilation error when your compatibility rules are violated.
I believe that this solution looks too complicated but if you really need this you can do this. It may take a day or so. Good luck.
Well, I am not aware of a compile time check but I do not think it is possible because how can the compiler know which value will be passed to the constructor (In case the value of your enum variable is calculated in runtime (e.g. by an If clause) ?
This can only be validated on runtime by using a validator method as you implemented for the enum types.
Example :
If in your code you have something like this :
EnumType1 enumVal;
if (<some condition>) {
enumVal = EnumType2.VALUE_SIX;
} else {
enumVal = EnumType2.VALUE_ONE;
}
There is no way the compiler can know which of the values will be assigned to enumVal so it won't be able to verify what is passed to the constructor until the if block is evaluated (which can be done only in runtime)

Set, Get and Constructors in Java

Despite Java tutorials, Wikipedia searches, stackoverflow trolling, and hours of reading code samples, constructors still confuse the crap out of me. I've got three related questions that I've been trying to answer to help ME understand constructors a little better.
First, I've been under the impression that constructors need to be named the same as their classes. Consider:
public class Money {
public Money(long l) {
this.value = l;
}
public Money(String s) {
this.value = toLong(s);
}
public long getLong() {
return this.value;
}
public String getString() {
return toString(this.value);
}
}
I see this as four constructors...correct? So it appears that constructors not named the same as the class which contains them allowable. Can someone confirm that?
Second, I seem to have a block against understanding the set and get methods. Consider:
public class GetSetSample {
public int getFoo() {
return int Foo;
}
public void setFoo(int fooValue) {
int Foo = fooValue;
}
}
Why can't I just do this:
public class getFoo(int fooValue){
foo=fooValue;
}
and use foo = getFoo(12) from some other class/method?
The third question is a little more esoteric, but will help me conceive of the bigger picture...which is my learning style, and conducive to my ability to trace program flow when debugging. The get and set methods suggest a "to" and "from" relationship to me. e.g., Passing a value "to" a constructor, receiving the result "from" the get method. It seems to me though that the "to" and "from" will change depending on your perspective. I think that any setMethod is setting parameters for an object, even though the variable comes FROM another class or method, and the GetMethod is getting the resulting object (say, this.foo) with the appropriately set parameter. No matter where the get or set is used, in a main method or a standalone class with a single constructor, 'set' is always associated with sending a parameter and get is always associated with receiving an object with that parameter. Is that a good understanding? or am I missing a vital part?
Question 1:
I see this as four constructors...correct?
No, that class has two constructors and two methods. (getLong and getString are the methods.)
Question 2:
Why can't I just do this:
public class getFoo(int fooValue){
foo=fooValue;
}
Well, that's trying to declare a class with parameters, and also you're setting a value in a get method, which would be extremely weird. It's not clear what you're trying to achieve here, but that code is thoroughly invalid.
Question 3:
The get and set methods suggest a "to" and "from" relationship to me.
Well it's not really a relationship IMO. A relationship suggests something longer term than either of these methods. A setter typically changes the state of an object in some way, and a getter typically just returns some aspect of the state of an object. It's not really clear what the rest of your explanation meant, because you're playing somewhat fast and loose with terminology. For example: "get is always associated with receiving an object with that parameter" doesn't really make sense to me. Objects don't have parameters, methods/constructors do - and getters can fetch primitive values or references...
I suspect you would benefit from reading the "Classes" part of the Java tutorial, which talks about constructors and methods.
Regarding the first answer, there's only 2 constructors. The difference is on how they are going to be called (called using a string will use the construction having a string has a parameter and called using a long will use the other one). So to answer, yes a constructor has the same name as the class.
The two constructors :
public Money(long l) {
this.value = l;
}
public Money(String s) {
this.value = toLong(s);
}
Regarding the second answer, getters ans setters are not meant to be classes. They are supposed to be within the class itself.
Consider this example which uses getter and setters to get ans set value for the printer class :
public class Printer {
#Inject #Informal Greeting greeting;
private String name;
private String salutation;
public void createSalutation() {
this.salutation = greeting.greet(name);
}
public String getSalutation() {
return salutation;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
A good read of this link could definitly help you out !
Java oriented-object principles
You've shown 2 constructors, which do need to have the same name as the class.
You've also shown two "getter" methods, which return the value of the class variable in the form requested by the user. You can also create "setter" methods, which are used to transfer values into class variables.
You use a constructor to create an object of a particular class, and optionally to set some or all of its internal state (that is, its member variables).
You use setters and getters to isolate the class variables from the outside world, so you don't need to allow other code to access them directly. Why? Because, before a setter updates a variable, it can verify that the new value is valid, and that the operation doesn't violate any or the rules (the "business logic") that are required for the class to work properly.
So you could add a setter and update the constructor to use it:
public Money(long l) {
setValue(l);
}
public Money(String s) {
setValue(toLong(s));
}
// Example setter that validates `l` by prohibiting negative values
public Money setValue(long l) {
if (l < 0) {
// Warn about negative values
}
this.value = l;
return this; // Return the current object to allow chaining; see below.
}
Note that a setter usually doesn't need to return a value (that is, it can be type void), but it's often helpful to return the object itself. That allows you to write code like this:
Money earnings = new Money().setValue(4).setOtherField("foo");
This creates an object of type Money, sets various attributes, and stores it in the variable earnings. Clearly, this isn't terribly useful for a simple class like this, but it can be very helpful for more complex classes:
Paycheck check = new Paycheck("MyCompany")
.setEmployee("YourName")
.setSalary(50,000)
.setPaySchedule(Schedule.BIWEEKLY)
.setAccountNumber("1234567")
.setDefaultTaxRate();
I would like to try to answer your implied conceptual questions -- you've already got plenty of examples of this and that, so I'm just going to try to explain. I have no doubt you have heard most of this -- maybe all of this -- before, but am not sure and not sure which parts.
Object-oriented programming centers mostly around objects; an object is an amalgamation of code and data. You define objects by writing a class, and you create one or more copies of the object defined by that class with the class constructor (called instantiating the class).
A parallel in other languages: you can have a data structure of related items and a set of subroutines that operate on that data structure. Think of a class as a way of collecting the items in that data structure and the subroutines that operate on it into one unit.
After you have invoked a constructor, you have a copy of the data defined in that class and a way to refer to that copy. By referring to that instance when you invoke a class method, you operate on that copy of the data with the methods defined in that class.
If you were to do this in a non-OO language, you could have a routine that created a copy of the data structure in memory and then only use the methods prescribed for it on that data structure. You could have a pointer to the copy in memory and pass that pointer as a parameter to every subroutine that operated on it, and in fact that's the way some pre-OO systems were programmed.
A constructor is similar to a method call that returns a value; it involves (or can involve) the execution of statements, and it always returns an object of that class. There are also differences between a constructor and a method; until the constructor completes, for instance, the object is not fully created and shouldn't have some methods invoked on it.
So I hope that helped; if there are conceptual things you still have questions about, perhaps something in here will help you form a specific question so we can explain things further.
Many people have found that if they have spent years learning languages such as COBOL and FORTRAN then changing to OO programming involves unlearning the old languages. I certainly found this when I first tackled C++ 20 years ago. From your description you are clearly struggling with the concepts and I sympathize.
I don't think there is a simple recipe. Practice at the simple examples and don't be disheartened. Don't be afraid to ask on SO - if the questions are clearly asked you will get a useful answer.
Get a good IDE (Eclipse, Netbeans, etc.) which allows you to "look inside" objects with the debugger. Hopefully at some stage things will click!
Question 1 - Basic Java Classes:
There's pretty much only 3 things you're going to find in a Java class
Field/attribute (Depending on your language of origin)
Method
Constructor (Which looks like a special kind of method)
Every class is going to have a class name that shares the name of the file it's located in. So to expand Money out a bit:
Money.java
----------
public class Money {
// This is a field/attribute
Long value;
// This is a constructor
public Money() {
this.value = Long(0L);
}
// This is a method
public Long getValue() {
return value;
}
// Another method
public void makeMoney(Long moreMoney) {
this.value = this.value + moreMoney;
}
} // Everything in here is part of the Money class
The only distinction between a constructor and a method is that a constructor has no specified return value, which is declared as a type right before the name of a potential method. Constructors do have to be named the same as the class they are contained in, but why is implied in how they are written.
Another way of looking at it is if you remove all of the non-type related Java keywords (public, private etc., but not things like float and int) from the front of the method you're looking at (A list of which you can find here), is there anything left in front of the method?
With the Money we have at the moment, it would look like this:
Money()
Long getValue()
void makeMoney()
The constructor is the one that has no type for the return value, because it is implied in the declaration.
Question 2/3 - Get/Set methods:
I'm going to say something potentially controversial, but don't worry about these yet. Get/Set are essentially patterns for Object Oriented development, and generally good Java style, but they aren't required (Last I checked, Android development actually discourages their use when possible for optimization reasons). Moreover, not all fields in your objects will be accessible or mutable so writing them isn't mandatory.
If you declare all of your fields as public (Like the 'value' field is implied to be right now), you simple can do this:
Money myMoney = new Money(new Long(40L));
System.out.println(myMoney.value) // 40
myMoney.value = new Long(20L);
System.out.println(myMoney.value) // 20
Aside from that, the notion of get() and set() are just methods. There is nothing special about them at all. The main reason they exist is because for general Object-Oriented programming, you shouldn't have to directly modify the internal workings of an object (This is the principle of Encapsulation). Everything you should need to affect state or get something out of it should be handled by a method.
In a pithy one-liner: If you need to know the fields of an object to use it, you designed it incorrectly.
Big Picture
So what get() and set() really are is a pair of commonly written methods that happen to affect a field in an object in an extremely simple way (get() is a simple access to a field, set() is assignment to that field). It's just that other methods you write will happen to do more complicated stuff than that.

Ways for lazy "run once" initialization in Java with override from unit tests

I'm looking for a piece of code which behaves a bit like a singleton but isn't (because singleton's are bad :) What I'm looking for must meet these goals:
Thread safe
Simple (Understand & use, i.e. few lines of code. Library calls are OK)
Fast
Not a singleton; for tests, it must be possible to overwrite the value (and reset it after the test).
Local (all necessary information must be in one place)
Lazy (run only when the value is actually needed).
Run once (code on RHS must be executed once and only once)
Example code:
private int i = runOnce(5); // Set i to 5
// Create the connection once and cache the result
private Connection db = runOnce(createDBConnection("DB_NAME"));
public void m() {
String greet = runOnce("World");
System.out.println("Hello, "+greet+"!");
}
Note that the fields are not static; only the RHS (right hand side) of the expression is ... well "static" to some degree. A test should be able to inject new values for i and greet temporarily.
Also note that this piece of code outlines how I intend to use this new code. Feel free to replace runOnce() with anything or move it to some other place (the constructor, maybe, or an init() method or a getter). But the less LOC, the better.
Some background information:
I'm not looking for Spring, I'm looking for a piece of code which can be used for the most common case: You need to implement an interface and there won't ever be a second implementation except for tests where you want to pass in mock objects. Also, Spring fails #2, #3 and #5: You need to learn the config language, you must set up the app context somewhere, it needs an XML parser and it's not local (information is spread all over the place).
A global config object or factory doesn't meet the bill because of #5.
static final is out because of #4 (can't change final). static smells because of classloader issues but you'll probably need it inside runOnce(). I'd just prefer to be able to avoid it in the LHS of the expression.
One possible solution might be to use ehcache with a default setup which would return the same object. Since I can put things in the cache, this would also allow to override the value at any time. But maybe there is a more compact/simple solution than ehcache (which again needs an XML config file, etc).
[EDIT] I'm wondering why so many people downvote this. It's a valid question and the use case is pretty common (at least in my code). So if you don't understand the question (or the reason behind it) or if you have no answer or you don't care, why downvote? :/
[EDIT2] If you look at the app context of Spring, you'll find that more than 99% of all beans have just a single implementation. You could have more but in practice, you simply don't. So instead of separating interface, implementation and configuration, I'm looking at something which has only an implementation (in the most simple case), a current() method and one or two lines of clever code to initialize the result for current() once (when it is called for the first time) but at the same times allows to override the result (thread safe, if possible). Think of it as an atomic "if(o==null) o = new O(); return o" where you can override the o. Maybe an AtomicRunOnceReference class is the solution.
Right now, I just feel that what we all have and use daily is not the optimum, that there is a baffling solution which will make us all slap our heads and say "that's it". Just as we felt when Spring came around a few years ago and we realized where all our singleton problems came from and how to solve them.
The best idiom for threadsafe initialization code (imho) is the lazy inner class. The classic version is
class Outer {
class Inner {
private final static SomeInterface SINGLETON;
static {
// create the SINGLETON
}
}
public SomeInterface getMyObject() {
return Inner.SINGLETON;
}
}
because it's threadsafe, lazy-loading and (imho) elegant.
Now you want testability and replaceability. It's hard to advise without knowing what exactly it is but the most obvious solution would be to use dependency injection, particularly if you're using Spring and have an application context anyway.
That way your "singleton"'s behaviour is represented by an interface and you simply inject one of those into your relevant classes (or a factory to produce one) and then you can of course replace it with whatever you like for testing purposes.
Here is a solution that fulfills all my requirements:
/** Lazy initialization of a field value based on the (correct)
* double checked locking idiom by Joschua Bloch
*
* <p>See "Effective Java, Second Edition", p. 283
*/
public abstract class LazyInit<T>
{
private volatile T field;
/** Return the value.
*
* <p>If the value is still <code>null</code>, the method will block and
* invoke <code>computeValue()</code>. Calls from other threads will wait
* until the call from the first thread will complete.
*/
#edu.umd.cs.findbugs.annotations.SuppressWarnings("UG_SYNC_SET_UNSYNC_GET")
public T get ()
{
T result = field;
if (result == null) // First check (no locking)
{
synchronized (this)
{
result = field;
if (result == null) // Second check (with locking)
{
field = result = computeValue ();
}
}
}
return result;
}
protected abstract T computeValue ();
/** Setter for tests */
public synchronized void set (T value)
{
field = value;
}
public boolean hasValue()
{
return field != null;
}
}
You can use IoC techniques even if you dont use an IoC framework (Spring/Guice/...). And it is in my opinion the only clean way to avoid a Singleton.
I think one solution you could use is providing a protected method which can be overriden in the test (a solution I've used before for testing legacy code).
So something like:
private SomeObject object;
protected SomeObject getObject() {
if (object == null) {
object = new SomeObject();
}
return object;
}
Then in your test class you can do:
public void setUp() {
MyClassUnderTest cut = new MyClassUserTest() {
#Override
protected SomeObject getObject() }
return mockSomeObject;
}
};
}
I have to say I'm not overly keen on this pattern as it exposes the protected field where you might not really want it, but it's useful for getting you out of some situations where injection isn't an option

Categories