I encountered a code where this() method in java takes three parameters two being integers and the third one is boolean value.
what exactly does that mean ? Are there any other variants of this() method ?
Hera is the actual code.
public SegmentConstructor(int seqNum_, int length_) {
this(seqNum_, length_, false);
}
Thank You..
It means that there is another constructor in the current class that has that signature.
public SegmentConstructor(int seqNum_, int length_) {
this(seqNum_, length_, false); // calls the constructor below.
}
public SegmentConstructor(int seqNum_, int length_, boolean required_) {
seqNum = seqNum_;
length = length_;
required = required_;
}
The this method is just a way to call one of your class's constructors from within another constructor, to help avoid code duplication. It can only be called on the first line of a constructor--never from within any other method.
this simply invokes another constructor to run. So, look for other constructors with that signature.
As said before this invokes another constructor, mostly as a convenience method.
Trivial example:
class A {
private int value;
public A(int val) {
value = val;
}
public A() {
this(0); //0 as default
}
}
Normally you do use calls to this() when the most specific constructor (that one with the most parameters) is not just assignment but contains more logic that you don't want to repeat/copy etc.
Just because it fits in here: super() can have parameters, too, i.e. this calls a super class' constructor with parameters from the sub class' constructor.
It is a constructor call. If your class implements different constructors with a differing number of arguments, you can chain your constructors like this:
class A {
public A(boolean arg) {
...
}
public A() {
this(false); // invokes the constructor with the boolean argument
}
}
Sometimes it makes sense to create a private constructor taking different arguments and provide public and/or protected constructors with other/fewer arguments and delegate object construction to that private constructor.
It is important to know that no other code may be placed before the call to this(...). However, after calling this(...), you can do everything you could in any other constructor.
Edit: Since this(...) calls a constructor, it can only be called from within other constructors (belonging to the same class).
class MyClass
{
private int var1;
private int var2;
private boolean flag;
public MyClass(int var1_,int var2_)
{
this(var1_,var2_,false);
}
public MyClass(int var1_,int var2_,boolean flag_)
{
var1 = var1_;
var2 = var2_;
flag = flag_;
}
public String toString()
{
return (new Boolean(flag).toString());
}
public static void main(String[] args)
{
MyClass my = new MyClass(5,6);
System.out.println(my);
}
}
So it works.
this() is not a method but is a reserved keyword pointing to a overloaded constructor of the same class.
The number of parameters you pass should point to an existing corresponding constructor defined in the class.
The super() also has the semantics however the constructor is defined in one of its parent hierarchy.
Related
in summary
WeatherCalculator calculator = WeatherCalculatorFactory.getInstance(Mode.valueOf(mode));
if(mode==Mode.DEW_POINT)
{
return new DewPointCalculator();
}
public class DewPointCalculator extends WeatherCalculator{
//default constructor
public DewPointCalculator()
{
this(null);
}
public WeatherCalculator(WeatherData weatherData) {
this.weatherData = weatherData;
calculate(); //calculate overriding
}
public WeatherCalculator()
{
this(null);
}
The line breaks are all different classes.
I wonder why calculate() in the constructor is executed when no object has been passed here.
You do call the first constructor with this(null). To call the second, no-argument constructor you can use this().
However, the second constructor still calls this(null) so the first constructor will be called either way.
The thing about null is that null can be anything, and anything can be null.
So by calling this(null) you are passing a WeatherData, it is just null (and using it would result in an error).
You are overloading constructors in class WeatherCalculator this is known as Explicit Constructor Invocation
You have two constructors in the class WeatherCalculator
WeatherCalculator() //Non parameterized constructor
WeatherCalculator(WeatherData weatherData) //parameterized constructor
what happens when you create an object of the WeatherCalculator class the WeatherCalculator() constructor is called which calls this(null) the parameterized constructor(WeatherCalculator(WeatherData weatherData)) and the calculate method is executed.
I am practicing 'this' keyword in constructors. I came to know 'this' will help to invoke constructor explicitly. But what is its use in real time.
Explicit Constructor Invocation.
class JBT {
JBT() {
this("JBT");
System.out.println("Inside Constructor without parameter");
}
JBT(String str) {
System.out
.println("Inside Constructor with String parameter as " + str);
}
public static void main(String[] args) {
JBT obj = new JBT();
}
}
In real life, you mostly use it to set default values (like you did in your example) so that you can simplify your classe's interface for the user.
Very often, this is also needed, when a class evolves over time and you add some new features. Consider this:
// First version of "Test" class
public class Test {
public Test(String someParam) {
...
}
}
// use of the class
Test t = new Test("Hello World"); // all is fine
Now, at a later date, you want to add a cool new switchable feature to Test, thus you alter the constructor to:
public Test(String someParam, boolean useCoolNewFeature)
Now, the original client code will not compile anymore, which is bad.
However, if you supply your old constructure signature additionally, all will be fine:
public Test(String someParam) {
this(someParam, false); // cool new feature defaults to "off"
}
this returns a reference to the current instance/object.
Well, you can use this keyword to call one constructor from another
constructor of the same class if you want to call a constructor from
base class or super class then you can use super keyword. Calling one
constructor from other is called Constructor chaining in Java.
Example:
public class ChainingDemo {
//default constructor of the class
public ChainingDemo(){
System.out.println("Default constructor");
}
public ChainingDemo(String str){
this();
System.out.println("Parametrized constructor with single param");
}
public ChainingDemo(String str, int num){
//It will call the constructor with String argument
this("Hello");
System.out.println("Parametrized constructor with double args");
}
public ChainingDemo(int num1, int num2, int num3){
// It will call the constructor with (String, integer) arguments
this("Hello", 2);
System.out.println("Parametrized constructor with three args");
}
public static void main(String args[]){
//Creating an object using Constructor with 3 int arguments
ChainingDemo obj = new ChainingDemo(5,5,15);
}
}
Output:
Default constructor
Parametrized constructor with single param
Parametrized constructor with double args
Parametrized constructor with three args
The output will be:
Inside Constructor with String parameter as JBT
Inside Constructor without parameter
because this("JBT") will invoke constructor with String argument
Please confirm me is this keyword refer to its owning class and this() method refers to its owning class constructors.
class Tester {
private String blogName;
public Tester() {
this("stackoverflow");
}
public Tester(String str) {
this.blogName = str;
}
public String getBlogName() {
return blogName;
}
}
It help me to if there are other differences between these.
this is a reference to the object on which behalf the current method was invoked. this(anything) is an invocation of constructor.
this("stackoverflow"); is calling the other constructor in the class (this is called a delegated constructor).
this.blogName= str1; is assigning a reference to whatever str1 is referring to to the field blogName. The this in this instance is redundant but is used to disambiguate a field name to an identically named function parameter.
The first example calls the overloaded constructor in the default constructor. You can call all overloaded constructors this way. It has to be the first line in the constructor, just like calls to super().
The second one shows how the special name this refers to the current instance within the class. It's only required to sort out name duplication:
public class ThisDemo {
private static final String DEFAULT_VALUE = "REQUIRED";
private String value;
public ThisDemo() {
this(DEFAULT_VALUE);
}
publi ThisDemo(String value) {
// Required here because the private member and parameter have same name
this.value = value;
}
public String getValue() {
// Not required here, but I prefer to add it.
return value;
}
}
this is a keyword in Java, it means its current instance of the class.
this("stackoverflow") is calling constructor in the class which will be a overloaded call. You can call any other constructors of the same class this way.
I'd like to better understand what is the difference in referring to a class field by using this.field and field alone as in
this.integerField = 5;
and
integerField = 5;
this keyword refers to the current object.
usually we use this.memberVariable to diffrentiate between the member and local variables
private int x=10;
public void m1(int x) {
sysout(this.x)//would print 10 member variable
sysout(x); //would print 5; local variable
}
public static void main(String..args) {
new classInst().m1(5);
}
Off from the concrete question,
the use of this In Overloaded constructors:
we can use this to call overloaded constructor like below:
public class ABC {
public ABC() {
this("example");to call overloadedconstructor
sysout("no args cons");
}
public ABC(String x){
sysout("one argscons")
}
}
The use of this keywords lets you disambiguate between member variables and locals, such as function parameters:
public MyClass(int integerField) {
this.integerField = integerField;
}
The code snippet above assigns the value of local variable integerField to the member variable of the class with the same name.
Some shops adopt coding standards requiring all member accesses to be qualified with this. This is valid, but unnecessary; in cases where no collision exists, removing this does not change the semantic of your program.
When you are in an instance method, you may need to specify to which scope you refer a variable from. For example :
private int x;
public void method(int x) {
System.out.println("Method x : " + x);
System.out.println("Instance x : " + this.x);
}
While, in this example, you have two x variables, one is a local method variable and one is a class variable. You may distinguish between the two with this to specify it.
Some people always use this before using a class variable. While it is not necessary, it may improve code readability.
As for polymorphism, you may refer to the parent class as super. For example :
class A {
public int getValue() { return 1; }
}
class B extends A {
// override A.getValue()
public int getValue() { return 2; }
// return 1 from A.getValue()
// have we not used super, the method would have returned the same as this.getValue()
public int getParentValue() { return super.getValue(); }
}
Both keywords this and super depend on the scope from where you are using it; it depends on the instance (object) you are working with at run-time.
It's exactly the same. Because you often type this.xyz it's a shortcut that means the same thing if there is a field by that name and there isn't a local variable that shadows it.
Though they look and act the same, there is a difference when the same name is shared between a field and a method argument, e.g.:
private String name;
public void setName(String name){
this.name = name;
}
name is the passed parameter, and this.name is the proper class field.
Notice that typing this.... prompts you a list of all the class fields [and methods] in many IDEs.
From the Java tutorials:
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.
So, when you call a method within a object the call looks like this:
public class MyClass{
private int field;
public MyClass(){
this(10); // Will call the constructor with a int argument
}
public MyClass(int value){
}
//And within a object, the methods look like this
public void myMethod(MyClass this){ //A reference of a object of MyClass
this.field = 10; // The current object field
}
}
I know abstract fields do not exist in java. I also read this question but the solutions proposed won't solve my problem. Maybe there is no solution, but it's worth asking :)
Problem
I have an abstract class that does an operation in the constructor depending on the value of one of its fields.
The problem is that the value of this field will change depending on the subclass.
How can I do so that the operation is done on the value of the field redefined by the subclass ?
If I just "override" the field in the subclass the operation is done on the value of the field in the abstract class.
I'm open to any solution that would ensure that the operation will be done during the instantiation of the subclass (ie putting the operation in a method called by each subclass in the constructor is not a valid solution, because someone might extend the abstract class and forget to call the method).
Also, I don't want to give the value of the field as an argument of the constructor.
Is there any solution to do that, or should I just change my design ?
Edit:
My subclasses are actually some tools used by my main program, so the constructor has to be public and take exactly the arguments with which they will be called:
tools[0]=new Hand(this);
tools[1]=new Pencil(this);
tools[2]=new AddObject(this);
(the subclasses are Hand, Pencil and AddObject that all extend the abstract class Tool)
That's why I don't want to change the constructor.
The solution I'm about to use is to slightly change the above code to:
tools[0]=new Hand(this);
tools[0].init();
tools[1]=new Pencil(this);
tools[1].init();
tools[2]=new AddObject(this);
tools[2].init();
and use an abstract getter to acces the field.
How about abstract getter/setter for field?
abstract class AbstractSuper {
public AbstractSuper() {
if (getFldName().equals("abc")) {
//....
}
}
abstract public void setFldName();
abstract public String getFldName();
}
class Sub extends AbstractSuper {
#Override
public void setFldName() {
///....
}
#Override
public String getFldName() {
return "def";
}
}
Also, I don't want to give the value
of the field as an argument of the
constructor.
Why not? It's the perfect solution. Make the constructor protected and offer no default constructor, and subclass implementers are forced to supply a value in their constructors - which can be public and pass a constant value to the superclass, making the parameter invisible to users of the subclasses.
public abstract class Tool{
protected int id;
protected Main main;
protected Tool(int id, Main main)
{
this.id = id;
this.main = main;
}
}
public class Pencil{
public static final int PENCIL_ID = 2;
public Pencil(Main main)
{
super(PENCIL_ID, main);
}
}
How about using the Template pattern?
public abstract class Template {
private String field;
public void Template() {
field = init();
}
abstract String init();
}
In this way, you force all subclasses to implement the init() method, which, since it being called by the constructor, will assign the field for you.
You can't do this in the constructor since the super class is going to be initialized before anything in the subclass. So accessing values that are specific to your subclass will fail in your super constructor.
Consider using a factory method to create your object. For instance:
private MyClass() { super() }
private void init() {
// do something with the field
}
public static MyClass create() {
MyClass result = new MyClass();
result.init();
return result;
}
You have an issue in this particular sample where MyClass can't be subclassed, but you could make the constructor protected. Make sure your base class has a public / protected constructor also for this code. It's just meant to illustrate you probably need two step initialization for what you want to do.
Another potential solution you could use is using a Factory class that creates all variants of this abstract class and you could pass the field into the constructor. Your Factory would be the only one that knows about the field and users of the Factory could be oblivious to it.
EDIT: Even without the factory, you could make your abstract base class require the field in the the constructor so all subclasses have to pass in a value to it when instantiated.
Also, I don't want to give the value of the field as an argument of the constructor.
Is there any solution to do that, or should I just change my design ?
Yes, I think you should change your design so that the subclass passes the value to the constructor. Since the subclass portion of your object isn't initialized until after the superclass constructor has returned, there's really no other clean way of doing it. Sure, this'd work:
class Super {
protected abstract int abstractField();
protected Super() { System.out.println("Abstract field: " + abstractField); }
}
class Sub {
protected int abstractField(){ return 1337; }
}
... since the implementation of abstractField() doesn't operate on object state. However, you can't guarantee that subclasses won't think it's a great idea to be a little more dynamic, and let abstractField() returns a non-constant value:
class Sub2 {
private int value = 5;
protected int abstractField(){ return value; }
public void setValue(int v){ value = v; }
}
class Sub3 {
private final int value;
public Sub3(int v){ value = v; }
protected int abstractField(){ return value; }
}
This does not do what you'd expect it to, since the initializers and constructors of subclasses run after those of the superclass. Both new Sub2() and new Sub3(42) would print Abstract field: 0 since the value fields haven't been initialized when abstractField() is called.
Passing the value to the constructor also has the added benefit that the field you store the value in can be final.
If the value is determined by the type of subclass, why do you need a field at all? You can have a simple abstract method which is implemented to return a different value for each subclass.
I think you need a factory (aka "virtual constructor") that can act on that parameter.
If it's hard to do in a given language, you're probably thinking about it incorrectly.
If I understand you correctly: You want the abstract class's constructor to do something depending on a field in the abstract class but which is set (hopefully) by the subclass?
If I got this wrong you can stop reading ...
But if I got it right then you are trying to do something that is impossible. The fields of a class are instantiated in lexical order (and so if you declare fields "below", or "after", the constructor then those will not be instantiated before the constructor is called). Additionally, the JVM runs through the entire superclass before doing anything with the subclass (which is why the "super()" call in a subclass's constructor needs to be the first instruction in the constructor ... because this is merely "advice" to the JVM on how to run the superclass's constructor).
So a subclass starts to instantiate only after the superclass has been fully instantiated (and the superclass's is constructor has returned).
And this is why you can't have abstract fields: An abstract field would not exist in the abstract class (but only in the subclass) and so is seriously(!) "off limits" to the super (abstract) class ... because the JVM can't bind anything references to the field (cause it doesn't exist).
Hope this helps.