How to avoid code duplication in overloaded constructors? - java

Say that I have one constructor that takes an input and another that uses a default value. Both constructors then proceed to process this data in exactly the same way. (Example below.) What are my options to avoid code duplication in this case?
(I've read the post how to reduce the code of constructor overloading, where the top answer suggests using the keyword "this". In my case, I guess I would need to use "this" to call the first constructor from the second one after the input has been stored. This however results in a compilation error: "call to this must be first statement in constructor".)
Example code:
public class A {
public A(String a) {
//process a
}
public A() {
String a = "defaultString";
//process a
}
}
EDIT: I'm taking a lot of fire for using an input dialog call in a class constructor (which I'm aware isn't exactly good practice). So I've changed the code example to direct the discussion away from this :).

One way is to have an init method:
public class A {
public A(String a) {
init(a);
}
public A() {
String a = "defaultString";
init(a);
}
private void init(String a) {
//process a
}
}

Say that I have one constructor that takes an input and another that asks for it via an input dialog.
Don't do that. It will make for horribly entangled and hard to maintain code in the long run. At least try to seperate UI concerns (input dialogs etc) from your object model (which you can feed a string in the constructor).
In my honest opinion you really don't want an overloaded constructor here.

You may want to try chaining your constructors:
public class A {
public A(String a) {
//process a
}
public A() {
this("defaultString");
}
}
If you want to use a dialog to get the string, I recommend you present the dialog before calling this constructor.

I think this is the preferred method:
public class A {
public A(String a) {
//process a
}
public A() {
this(JOptionPane.showInputDialog("a"));
}
}

I'm not sure it is ever a good idea to call something like a JOptionPane from a constructor. This is just an idea but you really should take the buildA from a static method and perform it where you actually are intending on asking the user for input and then just call a single constructor.
public class A {
public A(String a) {
this.a = a;
}
public static A buildA(String input){
if(input == null){
input = JOptionPane.showInputDialog("a");
}
return new A(input);
}
}

Another option for reducing code duplication between constructors is to use an initialization block. Initialization block code will run before the constructor.
See
http://geekexplains.blogspot.com/2009/06/initializer-blocks-their-alternatives.html for an example, or
http://blog.sanaulla.info/2008/06/30/initialization-blocks-in-java/ for discussion of both static initializer blocks and instance initializer blocks.
Using this method, you could put the common code into the initializer block, then leave the different logic in the specific constructor.
public class A {
{
//initializer block - common code here
}
public A(String a) {
//constructor - specific code here
}
public A() {
//constructor - specific code here
}
}
This may not be ideal in all situations, but it is another way to approach the problem that I didn't see mentioned yet.

Related

Is there a more specific reason to use "this" in Java other than style and readability? [duplicate]

I know that this refers to a current object. But I do not know when I really need to use it. For example, will be there any difference if I use x instead of this.x in some of the methods? May be x will refer to a variable which is local for the considered method? I mean variable which is seen only in this method.
What about this.method()? Can I use it? Should I use it. If I just use method(), will it not be, by default, applied to the current object?
The this keyword is primarily used in three situations. The first and most common is in setter methods to disambiguate variable references. The second is when there is a need to pass the current class instance as an argument to a method of another object. The third is as a way to call alternate constructors from within a constructor.
Case 1: Using this to disambiguate variable references. In Java setter methods, we commonly pass in an argument with the same name as the private member variable we are attempting to set. We then assign the argument x to this.x. This makes it clear that you are assigning the value of the parameter "name" to the instance variable "name".
public class Foo
{
private String name;
public void setName(String name) {
this.name = name;
}
}
Case 2: Using this as an argument passed to another object.
public class Foo
{
public String useBarMethod() {
Bar theBar = new Bar();
return theBar.barMethod(this);
}
public String getName() {
return "Foo";
}
}
public class Bar
{
public void barMethod(Foo obj) {
obj.getName();
}
}
Case 3: Using this to call alternate constructors. In the comments, trinithis correctly pointed out another common use of this. When you have multiple constructors for a single class, you can use this(arg0, arg1, ...) to call another constructor of your choosing, provided you do so in the first line of your constructor.
class Foo
{
public Foo() {
this("Some default value for bar");
//optional other lines
}
public Foo(String bar) {
// Do something with bar
}
}
I have also seen this used to emphasize the fact that an instance variable is being referenced (sans the need for disambiguation), but that is a rare case in my opinion.
The second important use of this (beside hiding with a local variable as many answers already say) is when accessing an outer instance from a nested non-static class:
public class Outer {
protected int a;
public class Inner {
protected int a;
public int foo(){
return Outer.this.a;
}
public Outer getOuter(){
return Outer.this;
}
}
}
You only need to use this - and most people only use it - when there's an overlapping local variable with the same name. (Setter methods, for example.)
Of course, another good reason to use this is that it causes intellisense to pop up in IDEs :)
The only need to use the this. qualifier is when another variable within the current scope shares the same name and you want to refer to the instance member (like William describes). Apart from that, there's no difference in behavior between x and this.x.
"this" is also useful when calling one constructor from another:
public class MyClass {
public MyClass(String foo) {
this(foo, null);
}
public MyClass(String foo, String bar) {
...
}
}
There are a lot of good answers, but there is another very minor reason to put this everywhere. If you have tried opening your source codes from a normal text editor (e.g. notepad etc), using this will make it a whole lot clearer to read.
Imagine this:
public class Hello {
private String foo;
// Some 10k lines of codes
private String getStringFromSomewhere() {
// ....
}
// More codes
public class World {
private String bar;
// Another 10k lines of codes
public void doSomething() {
// More codes
foo = "FOO";
// More codes
String s = getStringFromSomewhere();
// More codes
bar = s;
}
}
}
This is very clear to read with any modern IDE, but this will be a total nightmare to read with a regular text editor.
You will struggle to find out where foo resides, until you use the editor's "find" function. Then you will scream at getStringFromSomewhere() for the same reason. Lastly, after you have forgotten what s is, that bar = s is going to give you the final blow.
Compare it to this:
public void doSomething() {
// More codes
Hello.this.foo = "FOO";
// More codes
String s = Hello.this.getStringFromSomewhere();
// More codes
this.bar = s;
}
You know foo is a variable declared in outer class Hello.
You know getStringFromSomewhere() is a method declared in outer class as well.
You know that bar belongs to World class, and s is a local variable declared in that method.
Of course, whenever you design something, you create rules. So while designing your API or project, if your rules include "if someone opens all these source codes with a notepad, he or she should shoot him/herself in the head," then you are totally fine not to do this.
this is useful in the builder pattern.
public class User {
private String firstName;
private String surname;
public User(Builder builder){
firstName = builder.firstName;
surname = builder.surname;
}
public String getFirstName(){
return firstName;
}
public String getSurname(){
return surname;
}
public static class Builder {
private String firstName;
private String surname;
public Builder setFirstName(String firstName) {
this.firstName = firstName;
return this;
}
public Builder setSurname(String surname) {
this.surname = surname;
return this;
}
public User build(){
return new User(this);
}
}
public static void main(String[] args) {
User.Builder builder = new User.Builder();
User user = builder.setFirstName("John").setSurname("Doe").build();
}
}
Unless you have overlapping variable names, its really just for clarity when you're reading the code.
#William Brendel answer provided three different use cases in nice way.
Use case 1:
Offical java documentation page on this provides same use-cases.
Within an instance method or a constructor, this is a reference to the current object — the object whose method or constructor is being called. You can refer to any member of the current object from within an instance method or a constructor by using this.
It covers two examples :
Using this with a Field and Using this with a Constructor
Use case 2:
Other use case which has not been quoted in this post: this can be used to synchronize the current object in a multi-threaded application to guard critical section of data & methods.
synchronized(this){
// Do some thing.
}
Use case 3:
Implementation of Builder pattern depends on use of this to return the modified object.
Refer to this post
Keeping builder in separate class (fluent interface)
Google turned up a page on the Sun site that discusses this a bit.
You're right about the variable; this can indeed be used to differentiate a method variable from a class field.
private int x;
public void setX(int x) {
this.x=x;
}
However, I really hate that convention. Giving two different variables literally identical names is a recipe for bugs. I much prefer something along the lines of:
private int x;
public void setX(int newX) {
x=newX;
}
Same results, but with no chance of a bug where you accidentally refer to x when you really meant to be referring to x instead.
As to using it with a method, you're right about the effects; you'll get the same results with or without it. Can you use it? Sure. Should you use it? Up to you, but given that I personally think it's pointless verbosity that doesn't add any clarity (unless the code is crammed full of static import statements), I'm not inclined to use it myself.
Following are the ways to use ‘this’ keyword in java :
Using this keyword to refer current class instance variables
Using this() to invoke current class constructor
Using this keyword to return the current class instance
Using this keyword as method parameter
https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
when there are two variables one instance variable and other local variable of the same name then we use this. to refer current executing object to avoid the conflict between the names.
this is a reference to the current object. It is used in the constructor to distinguish between the local and the current class variable which have the same name. e.g.:
public class circle {
int x;
circle(int x){
this.x =x;
//class variable =local variable
}
}
this can also be use to call one constructor from another constructor. e.g.:
public class circle {
int x;
circle() {
this(1);
}
circle(int x) {
this.x = x;
}
}
Will be there any difference if I use "x" instead of "this.x" in some of the methods?
Usually not. But it makes a difference sometimes:
class A {
private int i;
public A(int i) {
this.i = i; // this.i can be used to disambiguate the i being referred to
}
}
If I just use "method()", will it not be, by default, applied to the current object?
Yes. But if needed, this.method() clarifies that the call is made by this object.
this does not affect resulting code - it is compilation time operator and the code generated with or without it will be the same. When you have to use it, depends on context. For example you have to use it, as you said, when you have local variable that shadows class variable and you want refer to class variable and not local one.
edit: by "resulting code will be the same" I mean of course, when some variable in local scope doesn't hide the one belonging to class. Thus
class POJO {
protected int i;
public void modify() {
i = 9;
}
public void thisModify() {
this.i = 9;
}
}
resulting code of both methods will be the same. The difference will be if some method declares local variable with the same name
public void m() {
int i;
i = 9; // i refers to variable in method's scope
this.i = 9; // i refers to class variable
}
With respect to William Brendel's posts and dbconfessions question, regarding case 2. Here is an example:
public class Window {
private Window parent;
public Window (Window parent) {
this.parent = parent;
}
public void addSubWindow() {
Window child = new Window(this);
list.add(child);
}
public void printInfo() {
if (parent == null) {
System.out.println("root");
} else {
System.out.println("child");
}
}
}
I've seen this used, when building parent-child relation's with objects. However, please note that it is simplified for the sake of brevity.
To make sure that the current object's members are used. Cases where thread safety is a concern, some applications may change the wrong objects member values, for that reason this should be applied to the member so that the correct object member value is used.
If your object is not concerned with thread safety then there is no reason to specify which object member's value is used.

Parameter vs field

I'm creating an abstract class with an abstract method example(boolean b, String s) that takes 2 parameters.
I want to create some methods for use inside that abstract method, but I need them to use those same parameters. So instead of constantly using foo(b,s), it would be nicer to just use foo().
I thought I could somehow store them in the class. However, my method is potentially spammed so it must not be slower.
public abstract class Example {
public abstract void example(boolean b, String s);
public void foo() {
// This method needs the parameters from the above method.
}
}
Possible solution:
public abstract class Example {
protected boolean b;
protected String s;
public abstract void example();
public void foo() {
// This method can now use 'b' and 's'
}
public void run(boolean b, String s) {
this.b = b;
this.s = s;
example();
}
}
If I use these parameters like in the last example above, will it make the process any slower?
Will it cause problems if a thread wants to use this method while another is not finished yet?
Before dealing with speed, let's deal with correctness:
Will it cause problems if a thread wants to use this method while another is not finished yet?
Assuming that both threads share the same object, the answer is "yes".
However, if you can make it so that each thread uses its own instance of your class, the answer would be "no", because re-assignments from other threads is possible only on shared objects.
If I use these parameters like in the last example above, will it make the process any slower?
Any speed difference between the two implementations would be minimal, falling into category of premature micro-optimizations. If saving parameters on the object makes sense from readability perspective, and if it does not create concurrency issues, do it; otherwise, keep using parameters.
If you have some methods which you want implementations of example() to use, and they need invocation-specific values of b and s, you can put those methods in an inner class:
class Example {
final class Inner {
final boolean b;
final String s;
Inner(boolean b, String s) {
this.b = b; this.s = s;
}
void foo() {
// This can use the values of b and s passed to run().
}
}
public abstract void example(Inner inner);
public void run(boolean b, String s) {
example(new Inner(b, s));
}
}
This is thread safe (with respect to b and s) because you're not storing the values in shared mutable fields.
Will it cause problems if a thread wants to use this method while
another is not finished yet?
Yes its a issue when more than two threads executing the same method and it will be race condition. Ideally you should not have any state in service class as you will run into issues in case of multiple threads
In terms of performance it wont have any impact
You should pass it as method parameters. If not possible due to some issue you can think of putting it in ThreadLocal
To answer your question:
If I use these parameters like in the last example above, will it make the process any slower?
Yes, anything executing within the code takes time. Setting the variables will take a nanosecond or two to execute; although this time increase it insignificant and not worth even considering.
Will it cause problems if a thread wants to use this method while another is not finished yet?
Depends.
Yes:
Do both threads share the object?
Do both modify the state of the object?
Do both threads concurrently access the object?
No:
Will the object be immutable.
Will the object be synchronized
If the object is used by both threads the way it is now, you will most likely occur problems.
I decided to create a class Execution that acts as an overlay to the parameters and also contains the methods that require those.
public class Execution {
public final boolean b;
public final String s;
Execution(boolean b, String s) {
this.b = b;
this.s = s;
}
public void foo(); // Uses 'b' and 's'
}
Abstract class:
public abstract class Example {
public abstract void example(Execution e);
public final void run(boolean b, String s) {
example(new Execution(b, s);
}
}
Implementation:
public class ExampleExample extends Example {
#Override
public void foo(Execution e) {
/*
* Do whatever you want because
* you have 'b', 's' and 'foo()'
* and whatever methods
* added to 'Execution'
*
*/
}
}
I don't know how it will affect the performance, doing it this way. But it solved the dilemma.
Thanks for all your suggestions!

Init block VS init() private method called in constructor

I know there are several ways to initialize stuff at instance creation in Java, but I'm interested in the difference between the following 2 possibilities.
Case 1:
{
// common init code for all constructors
}
public MyType() {
super();
// specific init code
}
public MyType(Object arg) {
super(arg);
// specific init code
}
Case 2:
public MyType() {
super();
init();
// specific init code
}
public MyType(Object arg) {
super(arg);
init();
// specific init code
}
private void init() {
// common init code for all constructors
}
I believe these 2 cases are equivalent in terms of code. I think the first is faster because there is 1 less method call, but on the other hand it might be confusing for someone who is not very knowledgeable about initialization.
Is there another difference that I have missed that could lead us to choose one over the other? Which option should I use preferably?
Note: the init() method is private, and I know a different visibility could lead to initialization bugs (when subclassing), this is not the point.
Maybe the first is faster because there is 1 less method call, but I think it is less readable.
I wouldn't even consider efficiency here as it would make just a minor difference of method call. But why do you think it is less readable? It's a well known feature of Java language.
Which option should I use preferably?
The benefit of first approach is, you've to write less code. And there is slight chance of human error in second approach. Generally you would use instance initializer block when you want the initialization to be done in every constructor. That saves you from explicitly writing same code in all constructor. With the other approach, you have to remember to invoke init() method from all the constructors.
But if you want some initialization to be part of some constructor, then the second approach might be useful. But that is very rare IMO.
In short, init code in first case will be called before constructor, in second - after.
Check out this question.
General rule is to avoid constructions like theese and use static-factory-methods instead.
Order might matter then calling this() instead of super():
Consider code:
public class InitOrderTest {
static class Super {
Super() {
System.out.println("Super constructor");
}
}
static class Puper extends Super {
{
System.out.println("Code block");
}
Puper() {
this("Self constructor");
init();
}
public Puper(String inner) {
System.out.println(inner);
}
private void init() {
System.out.println("Init call");
}
}
public static void main(String[] args) {
new Puper();
}
}
It prints:
Super constructor
Code block
Self constructor
Init call

Method call in constructor does not work, made method final and still does not work

I am tring to set my objects state in my constructor. I call the setState method.
This keeps giving me null. I read that you can't call methods that can be overridden in a constructor, so I figured that was why. I made the setState method final and still see the issue.
Is it ok to just do myState = x; in the constructor instead of calling setState(x)?
Also any thoughts why the call to setState in the constructor does not work even if the method is final?
One more point is that the class that all this is done in is abstract, not sure if that makes any difference.
Language is Java.
I am not sure about posting code, my company is sensitive to that. Don't want to get in trouble with my employer.
I will post some generic code
public abstract class Abc
public Abc()
{
setState(uninit);
}
public final void setState(state s)
{
myState = s;
}
This does not work, if I change the line
setState(uninit);
to
myState = uninit;
it works, but I am not sure this is a good idea, because I have a setter for the state.
I suppose that you forgot to call the super constructor in the sub-class constructor.
super();
It is something like
public class sub_abc extends abc}
public sub_abc(){
super();
...
}
}
Not sure what your actual code is but I don't find the parameter name in the formal parameter list of the setState() method.
public abstract class abc
{
public abc()
{
setState(uninit);
}
public final void setState(state s) //Seems to be something like this.
{
myState = s;
}
}
Additionally, you must follow the Java naming-conventions. Accordingly your class name abc should be replaced as Abc and so on.
Executing myState = x; in the constructor has the exact same effect as calling setState(uninit);; at least as far as I can imagine your original code to be. In that case then, the error must be somewhere else. Perhaps you are calling setState again? Or something else that is different between the two tests. I would put a breakpoint in the constructor and step through the code.
There is nothing here that your company can object to as being sensitive. If it makes you more comfortable, use an online compiler such as ideone
I usually initialize my class variables in the constructor like that. The getters and setters are usually only for other classes to use, so I see no reason why you cannot just use myState = uninit;
public abstract class abc {
private State uninit;
public abc()
{
myState = uninit;
}
public final void setState(State newState)
{
myState = newState;
}
}

How to hide a public method?

I have a method in my static state machine that is only used once when my application is first fired up. The method needs to be public, but I still want it hidden. Is there a way to use an annotation or something that will hide the method from the rest of the project?
You cannot make a public method hidden (unless you can declare it private). You can however put in a subclass and only let the users of the object know the type of the superclass, that is:
class A {
//Externally visible members
}
class B extends A {
//Secret public members
}
Then you instantiate the class B, but only let the type A be known to others...
Once you declare public method it becomes part of your class's contract. You can't hide it because all class users will expect this method to be available.
You could use package level instead of public. That way it can only be called by your application.
If a method is public, it can't be hidden. What you may really be looking for is just a way to restrict access to calling a method. There are other ways to achieve a similar effect.
If there are some things that your state machine does that are "only used once when my application is first fired up" it sounds a lot like those are things that could happen in the constructor. Although it depends on how complex those tasks are, you may not want to do that at construction time.
Since you said your state machine is static, is it also a Singleton? You could maybe use the Singleton Pattern.
public class SimpleStateMachine {
private static SimpleStateMachine instance = new SimpleStateMachine();
private SimpleStateMachine() {
super();
System.out.println("Welcome to the machine"); // prints 1st
}
public static SimpleStateMachine getInstance() {
return instance;
}
public void doUsefulThings() {
System.out.println("Doing useful things"); // prints 3rd
}
}
Here's some code for a client of this Singleton:
public class MachineCaller {
static SimpleStateMachine machine = SimpleStateMachine.getInstance();
public static void main(String... args) {
System.out.println("Start at the very beginning"); // prints 2nd
machine.doUsefulThings();
}
}
Note that the SimpleStateMachine instance isn't built until the first time your class is accessed. Because it's declared as static in the MachineCaller client, that counts as a "first access" and creates the instance. Keep this tidbit in mind if you definitely want your state machine to perform some of those initialization tasks at the time your application starts up.
So, if you don't want to turn your state machine class into a true singleton... you can use a static initialization block do your one-time tasks the first time the class is accessed. That would look something like this:
public class SimpleStateMachine {
static {
System.out.println("First time tasks #1");
System.out.println("First time tasks #2");
}
public SimpleStateMachine() {
super();
System.out.println("Welcome to the machine");
}
public void doUsefulThings() {
System.out.println("Doing useful things");
}
}
While we're at it, since you mentioned that it's a state machine... the Head First Design Patterns book does a nice, easily understandable treatment of the State Pattern. I recommend reading it if you haven't already.
The idiomatic approach to doing this is to use interfaces to limit the visibility of your methods.
For example, say you have the following class:
public class MyClass {
public void method1() {
// ...
}
public void method2() {
// ...
}
}
If you want to limit some parts of the project to only see method1(), then what you do is describe it in an interface, and have the class implement that interface:
public interface Method1Interface {
public void method1();
}
...
public class MyClass implements Method1Interface {
public void method1() {
// ...
}
public void method2() {
// ...
}
}
Then, you can limit the visibility of the methods by choosing to pass the class around either as a MyClass reference, or as a Method1Interface reference:
public class OtherClass {
public void otherMethod1(MyClass obj) {
// can access both obj.method1() and obj.method2()
}
public void otherMethod2(Method1Interface obj) {
// can only access obj.method1(), obj.method2() is hidden.
}
}
A bonus of this approach is that it can also be easily extended. Say, for example, you now also want to independently control access to method2(). All you need do is create a new Method2Interface along the same lines as Method1Interface, and have MyClass implement it. Then, you can control access to method2() in exactly the same manner as method1().
This is a similar approach to that advocated in #MathiasSchwarz's answer, but is much more flexible:
The independent access control described in the preceding paragraph isn't possible with Mathias' technique, due to Java not supporting multiple inheritance.
Not requiring an inheritance relationship also allows more flexibility in designing the class hierarchy.
The only change required to the original class is to add implements Method1Interface, which means that it is a very low-impact refactor since existing users of MyClass don't have to be changed at all (at least, until the choice is made to change them to use Method1Interface).
An alternative solution: You can make it private and create a invokeHiddenMethod(String methodName, Object ... args) method using reflection.
You said that your public method is used only once when the application is started up.
Perhaps you could leave the method public, but make it do nothing after the first call?
There is a (non-)keyword level package level visibility. Instead of public, protected, or private, you use nothing.
This would make the method or class visible to the class and others in the package, but would give you a certain modicum of privacy. You may want to look at What is the use of package level protection in java?.
Hmm... You want a private method, but want to access it outside?
Try do this with reflection.
http://download.oracle.com/javase/tutorial/reflect/index.html
I have seen many Java programmers do something like this:
public static void main(String args[]) {
new MyClass();
}
So basically they create just one object of the class. If there is a method which should run only once, I guess this approach can achieve that. Your method will be called from inside the constructor. But since I don't know how your app works, what are the constraints, so it is just a thought.

Categories