How to allow variables being set only once in java - java

I need to implement a class in java where its field needs to be set only once, but it's value is not known at field declaration. To do so I have:
public class MyClass {
private String field1 = null;
public void setField1(String value) {
if (field1 == null) {
field1 = value;
}
}
}
However what I have do not prevent users to call setField1 more than once. That may lead to confusion where a user is trying to set it (without knowing it has been set somewhere else) and then the user will get confused by the field1 is not giving the value they set - until they go into the setField1 method to see what happened.
The other solution that I don't like is make a constructor to take into the value of field1, and then provide no setter. Because it makes the class a lot harder to be extended, when multiple String fields are needed - in this approach, the constructor will need to take in a couple String as parameters, and then the user can be so easily confused by/missing the parameters.
And apparently setting field1 as final won't work either.
What should I do to prevent the issue I mentioned above?

The common practice in such case is to throw a RuntimeException. In your case IllegalStateException suits best:
public void setField1(String value) {
if (field1 != null) {
throw new IllegalStateException("setField1 was already called");
}
field1 = Objects.requireNonNull(value);
}
Also note that it's better to check the passed string for null (I added Objects.requireNonNull for this).
You cannot control this at compile time, because it's impossible to analyze program to say exactly whether the method called once or more without actually running the program.

You should generally use the builder pattern for cases like this: https://en.wikipedia.org/wiki/Builder_pattern
MyClass instance = (new MyClassBuilder())
.setField1(...)
.setField2(...)
.build();
Your builder object lets you set all the fields and options you like, but the MyClass instance that it builds does not.

Related

Conventionally, can a set() method return a value in Java?

I am learning how to write neat and organized code in Java. Can a set() method return a value or is there a more efficient/readable way of doing this?
public class Car {
private boolean mHasAxles;
private boolean mHasTires;
private Tires mTires;
public setAxels(boolean hasAxles) {
mHasAxels = hasAxles;
}
public boolean hasAxles() {
return mHasAxles;
}
public boolean setTires(Tires tires) {
if(hasAxles()){
mTires = tires;
mHasTires = true;
return true; // Returns true if it was able to set tires
}
return false; // Returns false because car did not have axels
// Therefore, tires could not be set
}
}
In this example, my question is specifically about the setTires() method. Should the class check whether the car has axles when setting the tires or should the logic be left to the class that uses Car? Should the setTires() method be called something else since it returns a value?
Strictly conventionally - no, a setter usually returns void.
Having said that, you are free to return boolean if you wish - conventions are often broken (even in the internal java api's) and the method signature, including it's return type, should inspire an interested developer to navigate into the code to see exactly why a boolean is returned.
To make it clearer, you might want to use a different method name, e.g. setTiresIfAble(Tires tires), or you could alternatively return void and throw an Exception as per below:
public void setTires(Tires tires){
if(!hasAxels()) {
throw new IllegalStateException("no axels!");
}
mTires = tires;
mHasTires = true;
}
Incidentally, mHasTires is redudant, you can always check if tires == null.
Lastly, you can avoid the m or Hungarian notation in java (as per convention), like this:
public setAxels(boolean hasAxels){
this.hasAxels = hasAxels;
}
A setSomething method shouldn't return anything
A trySetSomethingmust return a boolean which say if the set has been successful or not.
Why ? When you are writting some code, in Java, in C++, in any langage, you want that any reader of your code, which is probably a human being, can access to the knownledge of most of what a method do, just reading his name.
To complete this assertion, we can study the case that a set can fail. There are two possibilities to deal with failures, depending on the scope of the method :
if the scope of setSomething is protected, private or package, it means that you have control, as API developper, on the way it will be called. Possible failures can be managed with assertion, or with RuntimeException (as it's not necessay to declare a throws clause in the method signature).
if the scope of setSomething is public, it means that you don't have control, as API developper, on the way it will be call. You have to warn the users of your API that the setSomething isn't error-safe. You have to manage the possible failures with an Exception which has to be declared in a throw clause.
You "can" return a value, but by convention setters don't return a value. As setters generally are used in a manner where one doesn't even reference a return value it is quite easy for any caller of your class to ignore that you are returning a value. Nothing stops the called from doing:
myCar.setTires(aTire);
...and ignoring you even return a Boolean, because that is the normal way setters are called and used. This defeats the purpose of your returning a value if the caller can just ignore it and the code appears correct.
My first inclination is to say throw an java.lang.IllegalArgumentException rather than return false.

Is there a nice way to "null" a member variable when returning the value from a method?

I have some code that looks like this, in order to ensure that Foo doesn't hold
on to a reference it no longer needs:
class Foo {
T field;
T method()
{
....
T tmp = field;
field = null;
return tmp;
}
}
This looks rather ugly. Is there any more pleasant way to take out the garbage?
Use a try-finally block
class Foo {
T field;
T method()
{
....
try {
....
return field;
} finally {
field = null;
}
}
}
Is there any more pleasant way to take out the garbage?
The short answer is no.
You could possibly do something using reflection (e.g. a helper method that takes the name of the field as a parameter, etcetera), allowing you to express the method body in one line. But that's NOT what I would call pleasant.
Some setter methods return the previous value of the thing being set. For instance, Map.put(key,value) returns the previous value associated with the key. You might use that idiom to finish your method with:
return setField( null );
to both set the field to null, and to return its (prior) value. This is certainly a little bit shorter: it turns three lines into one (at the cost of moving them someplace else, but that's not so much of a concern). Whether this is clearer or not, though, depends on whether your codebase makes much use of the "return the previous value" idiom. If you're not using it elsewhere, then this code isn't very clear (but you can add a comment, of course). If you use this idiom here, and you're using a "return the new value" idiom elsewhere (e.g., for method chaining), then this become very opaque.
Aside from those issues of clarity, it's also worth noting that this does violate the typical convention and JavaBeans "protocol" of setters being void methods. It also becomes a bit hairy if you have lots of these kinds of fields, as you start to need such a method for each one.
Your code would be like this:
class Foo {
T field;
T method() {
....
return setField( null );
}
T setField( T value ) {
T old = field;
field = value;
return old;
}
}

Access a private variable of the super() class in Java - JChart2D

I have extended a class in Java that has a private variable that I want to get the value of before it is changed. There are no methods to access this variable in the super class. I have tried super().m_zoomArea (the variable is in the ZoomableChart class of jChart2D). The variable is updated when the mouseDragged method is called. I have overridden this method and would like to get the value of the variable before it is updated.
You can access private variable of any class, but it's a bad idea, because you're breaking one of the basic principles of OOP - encapsulation.
But sometimes programmer are forced to break it. Here is the code, which solves your problem:
Extended class
public class ExtZoomableChart
extends ZoomableChart {
public Rectangle2D getZoomArea() {
try {
Field field = ZoomableChart.class.getDeclaredField("m_zoomArea");
field.setAccessible(true);
Object value = field.get(this);
field.setAccessible(false);
if (value == null) {
return null;
} else if (Rectangle2D.class.isAssignableFrom(value.getClass())) {
return (Rectangle2D) value;
}
throw new RuntimeException("Wrong value");
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
and call example:
public class Main {
public static void main(String[] args) {
ExtZoomableChart extZoomableChart = new ExtZoomableChart();
Rectangle2D d = extZoomableChart.getZoomArea();
System.out.println(d);
}
}
You don't need to extend ZoomableChart to get private variable. You can get it value almost from everywhere. But remember - usually it's a bad practice.
You can't. The whole point of it being private is that you can't get at the variable. If the class hasn't given any way of finding it out, you can't get it. That may or may not be a design flaw in the class, but unless you use reflection with suitable privileges (which I don't recommend - you're basically relying on private implementation details) you're going to have to think of an alternative approach.
You could use reflection but it's a bad idea. A private field is private because the developer doesn't want you to mess with it.
I won't give you the way to do it here, but if you really know what you do, follow the links below at your own risks. Again, you shouldn't even think about doing this.
On the same topic :
Does reflection breaks the idea of private methods, because private methods can be access outside of the class?
Accessing private variables in Java via reflection
Is it possible in Java to access private fields via reflection
You can't access private variables from outside of the class. In order to access it you would have to have it be protected.
You can do this with the Reflection API (Specifically, see the setAccessible() method). Anyway, this is a hack and may not work if there is a SecurityManager installed in the VM.

Getting value of public static final field/property of a class in Java via reflection

Say I have a class:
public class R {
public static final int _1st = 0x334455;
}
How can I get the value of the "_1st" via reflection?
First retrieve the field property of the class, then you can retrieve the value. If you know the type you can use one of the get methods with null (for static fields only, in fact with a static field the argument passed to the get method is ignored entirely). Otherwise you can use getType and write an appropriate switch as below:
Field f = R.class.getField("_1st");
Class<?> t = f.getType();
if(t == int.class){
System.out.println(f.getInt(null));
}else if(t == double.class){
System.out.println(f.getDouble(null));
}...
R.class.getField("_1st").get(null);
Exception handling is left as an exercise for the reader.
Basically you get the field like any other via reflection, but when you call the get method you pass in a null since there is no instance to act on.
This works for all static fields, regardless of their being final. If the field is not public, you need to call setAccessible(true) on it first, and of course the SecurityManager has to allow all of this.
I was following the same route (looking through the generated R class) and then I had this awful feeling it was probably a function in the Resources class. I was right.
Found this:
Resources::getIdentifier
Thought it might save people some time. Although they say its discouraged in the docs, which is not too surprising.
I was looking for how to get a private static field and landed here.
For fellow searchers, here is how:
public class R {
private static final int _1st = 0x334455;
}
class ReflectionHacking {
public static main(String[] args) {
Field field = R.class.getFieldDeclaration("_1st");
field.setAccessible(true);
int privateHidenInt = (Integer)field.get(null);
}
}

How to improve the builder pattern?

Motivation
Recently I searched for a way to initialize a complex object without passing a lot of parameter to the constructor. I tried it with the builder pattern, but I don't like the fact, that I'm not able to check at compile time if I really set all needed values.
Traditional builder pattern
When I use the builder pattern to create my Complex object, the creation is more "typesafe", because it's easier to see what an argument is used for:
new ComplexBuilder()
.setFirst( "first" )
.setSecond( "second" )
.setThird( "third" )
...
.build();
But now I have the problem, that I can easily miss an important parameter. I can check for it inside the build() method, but that is only at runtime. At compile time there is nothing that warns me, if I missed something.
Enhanced builder pattern
Now my idea was to create a builder, that "reminds" me if I missed a needed parameter. My first try looks like this:
public class Complex {
private String m_first;
private String m_second;
private String m_third;
private Complex() {}
public static class ComplexBuilder {
private Complex m_complex;
public ComplexBuilder() {
m_complex = new Complex();
}
public Builder2 setFirst( String first ) {
m_complex.m_first = first;
return new Builder2();
}
public class Builder2 {
private Builder2() {}
Builder3 setSecond( String second ) {
m_complex.m_second = second;
return new Builder3();
}
}
public class Builder3 {
private Builder3() {}
Builder4 setThird( String third ) {
m_complex.m_third = third;
return new Builder4();
}
}
public class Builder4 {
private Builder4() {}
Complex build() {
return m_complex;
}
}
}
}
As you can see, each setter of the builder class returns a different internal builder class. Each internal builder class provides exactly one setter method and the last one provides only a build() method.
Now the construction of an object again looks like this:
new ComplexBuilder()
.setFirst( "first" )
.setSecond( "second" )
.setThird( "third" )
.build();
...but there is no way to forget a needed parameter. The compiler wouldn't accept it.
Optional parameters
If I had optional parameters, I would use the last internal builder class Builder4 to set them like a "traditional" builder does, returning itself.
Questions
Is this a well known pattern? Does it have a special name?
Do you see any pitfalls?
Do you have any ideas to improve the implementation - in the sense of fewer lines of code?
The traditional builder pattern already handles this: simply take the mandatory parameters in the constructor. Of course, nothing prevents a caller from passing null, but neither does your method.
The big problem I see with your method is that you either have a combinatorical explosion of classes with the number of mandatory parameters, or force the user to set the parameters in one particular sqeuence, which is annoying.
Also, it is a lot of additional work.
public class Complex {
private final String first;
private final String second;
private final String third;
public static class False {}
public static class True {}
public static class Builder<Has1,Has2,Has3> {
private String first;
private String second;
private String third;
private Builder() {}
public static Builder<False,False,False> create() {
return new Builder<>();
}
public Builder<True,Has2,Has3> setFirst(String first) {
this.first = first;
return (Builder<True,Has2,Has3>)this;
}
public Builder<Has1,True,Has3> setSecond(String second) {
this.second = second;
return (Builder<Has1,True,Has3>)this;
}
public Builder<Has1,Has2,True> setThird(String third) {
this.third = third;
return (Builder<Has1,Has2,True>)this;
}
}
public Complex(Builder<True,True,True> builder) {
first = builder.first;
second = builder.second;
third = builder.third;
}
public static void test() {
// Compile Error!
Complex c1 = new Complex(Complex.Builder.create().setFirst("1").setSecond("2"));
// Compile Error!
Complex c2 = new Complex(Complex.Builder.create().setFirst("1").setThird("3"));
// Works!, all params supplied.
Complex c3 = new Complex(Complex.Builder.create().setFirst("1").setSecond("2").setThird("3"));
}
}
No, it's not new. What you're actually doing there is creating a sort of a DSL by extending the standard builder pattern to support branches which is among other things an excellent way to make sure the builder doesn't produce a set of conflicting settings to the actual object.
Personally I think this is a great extension to builder pattern and you can do all sorts of interesting things with it, for example at work we have DSL builders for some of our data integrity tests which allow us to do things like assertMachine().usesElectricity().and().makesGrindingNoises().whenTurnedOn();. OK, maybe not the best possible example but I think you get the point.
Why don't you put "needed" parameters in the builders constructor?
public class Complex
{
....
public static class ComplexBuilder
{
// Required parameters
private final int required;
// Optional parameters
private int optional = 0;
public ComplexBuilder( int required )
{
this.required = required;
}
public Builder setOptional(int optional)
{
this.optional = optional;
}
}
...
}
This pattern is outlined in Effective Java.
Instead of using multiple classes I would just use one class and multiple interfaces. It enforces your syntax without requiring as much typing. It also allows you to see all related code close together which makes it easier to understand what is going on with your code at a larger level.
IMHO, this seems bloated. If you have to have all the parameters, pass them in the constructor.
I've seen/used this:
new ComplexBuilder(requiredvarA, requiedVarB).optional(foo).optional(bar).build();
Then pass these to your object that requires them.
The Builder Pattern is generally used when you have a lot of optional parameters. If you find you need many required parameters, consider these options first:
Your class might be doing too much. Double check that it doesn't violate Single Responsibility Principle. Ask yourself why you need a class with so many required instance variables.
You constructor might be doing too much. The job of a constructor is to construct. (They didn't get very creative when they named it ;D ) Just like classes, methods have a Single Responsibility Principle. If your constructor is doing more than just field assignment, you need a good reason to justify that. You might find you need a Factory Method rather than a Builder.
Your parameters might be doing too little. Ask yourself if your parameters can be grouped into a small struct (or struct-like object in the case of Java). Don't be afraid to make small classes. If you do find you need to make a struct or small class, don't forget to refactor out functionality that belongs in the struct rather than your larger class.
For more information on when to use the Builder Pattern and its advantages you should check out my post for another similar question here
Question 1: Regarding the name of the pattern, I like the name "Step Builder":
http://rdafbn.blogspot.com/2012/07/step-builder-pattern_28.html
http://www.javacodegeeks.com/2013/05/building-smart-builders.html
Question 2/3: Regarding pitfalls and recommendations, this feels over complicated for most situations.
You are enforcing a sequence in how you use your builder which is unusual in my experience. I could see how this would be important in some cases but I've never needed it. For example, I don't see the need to force a sequence here:
Person.builder().firstName("John").lastName("Doe").build()
Person.builder().lastName("Doe").firstName("John").build()
However, many times the builder needed to enforce some constraints to prevent bogus objects from being built. Maybe you want to ensure that all required fields are provided or that combinations of fields are valid. I'm guessing this is the real reason you want to introduce sequencing into the building.
In this case, I like recommendation of Joshua Bloch to do the validation in the build() method. This helps with cross field validation because everything is available at this point. See this answer: https://softwareengineering.stackexchange.com/a/241320
In summary, I wouldn't add any complication to the code just because you are worried about "missing" a call to a builder method. In practice, this is easily caught with a test case. Maybe start with a vanilla Builder and then introduce this if you keep getting bitten by missing method calls.

Categories

Resources