Java equivalent of instance initializer called after constructor - java

I've been reading about instance initializers in Java, and it's been explained that code common to all constructors can be put into them because they are called every time a new instance of a class is created. Is there an equivalent of instance initializers that run after constructors, for code that would be common to all constructors, but depends on what happens in the constructors?

No, there isn't an exact equivalent. If you want to run some common code, you can always factor out a method and call it at the end of all your constructors:
public class C {
private int x = 5;
private String y;
public C(int x) {
this.x = x;
endConstructor();
}
public C(String x) {
this.x = x.length;
endConstructor();
}
private void endConstructor() {
y = x + "!";
}
}
Sometimes, what seems like a situation where you want to call the same code at the "end" of all constructors can be refactored so that this code is in a single main constructor. Then, all other constructors call it using this(). For the example above:
public class C {
private int x = 5;
private String y;
public C(int x) {
this.x = x;
y = x + "!";
}
public C(String x) {
this(x.length);
}
}
The main constructor can be private, if appropriate.

Something like the #PostConstruct annotation can be used.
If your class has its dependencies injected using setter methods, then its constructor won't fully initialize an instance. Thus, additional "initializations" need to be performed after all the setter methods have been called.

If you think something happens in constructor:
class X {
private int x;
public X() {
// Code that sets x
// =-=-= HERE =-=-=
}
}
Insert the code you want to happen after the constructor... At the end of constructor.
If you have many constructors and don't want to duplicate code:
class X {
private int x;
public X() {
// Code that sets x
init();
}
public X(int x2) {
x = x2;
init();
}
private void init() {
// =-=-= HERE =-=-=
}
}
If every constructor invokes init, we may say this is invoked as a part of constructor, not after it. Imagine a train with one additional car following it, 50cm from it. Both have the same destination/time. Why couldn't we connect the train with standalone car?

Related

Define identical treatment of private subclass members in superclass

I've got this parent class:
abstract class Parent {
abstract int getX();
}
And two different subclass implementations:
class AgnosticChild extends Parent {
private int x = 5;
#Override
int getX() {
return x;
}
}
class ManipulativeChild extends Parent {
private static int x = 5;
ManipulativeChild() {
x++;
}
#Override
int getX() {
return x;
}
}
Both getX() implementations are identical. Is there any way to get rid of this redundancy while keeping the different implementations for x? Assume that the getX() implementation is a lot more elaborate in practice.
No, the two implementations are not identical - one accesses a static field, and the other accesses an instance field. So although they look identical, they're functionally very different; and there's no opportunity for re-use here, without changing the behaviour of your classes.
You could pull up the int variable to Parent class and implement getX method there
abstract class Parent {
private int x;
public Parent(int x) {
this.x = x;
}
public int getX() {
return x;
}
}
class AgnosticChild extends Parent {
public AgnosticChild() {
super(5);
}
}
class ManipulativeChild extends Parent {
ManipulativeChild() {
super(6);
}
}
Update: The upper code snippet only equal to your code if you want to declare the x in ManipulativeChild as non-static field. Otherwise these are two different implementation and cannot be refactored in the proposed way.

How would I access an int variable from one class to another? (Java)

For example:
In Class One
int killcount = 0;
In Class Two
killcount = 5;
All I want to do I get the variable from one class to another class. How would I do that?
Before trying to work with Bukkit I'd recommend you to get some Java experience first. That's not meant as an insult, but it can get quite confusing if you do it the other way round. Anyways, if you still want to know the answer to your question:
You'll have to create a getter & setter for your "killcount" variable.
class Xyz {
private int killcount;
public void setKillcount(int killcount) {
this.killcount = killcount;
}
public int getKillcount() {
return this.killcount;
}
}
Of course this is a simplified version without checks, but if you want to access the variable from a different class you can create an instance and use the methods to modify it.
public void someMethod() {
Xyz instance = new Xyz();
instance.setKillcount(instance.getKillcount() + 1);
//this would increase the current killcount by one.
}
Keep in mind that you'll have to use the same instance of the class if you want to keep your values, as creating a new one will reset them to default. Therefore, you might want to define it as a private variable too.
Consider the examples
public class Test {
public int x = 0;
}
This variable x can be accessed in another class like
public class Test2 {
public void method() {
int y = new Test().x;
// Test.x (if the variable is declared static)
}
}
Ideally, the instance variables are made private and getter methods are exposed to access them
public class Test {
private int x = "test";
public int getX() {
return x;
}
public void setX(int y) {
x = y;
}
}

Using this operator to get a variable in a constructor?

When the 'this' operator is used to reference a variable in the current object is that included in the constructor? For example...
public class Mechanics {
public Mechanics() {
int x = 1;
}
public int returnX(){
return this.x;
{
}
As the constructor is called when the object is created will the 'this' operator return the x in the constructor or only a variable that is outside?
Thanks
Your code is not valid and won't compile. x as defined in the constructor is local to the constructor only. It is not a field of the Mechanics class. To be able to use x somewhere else, you need to declare it as a field of the class:
public class Mechanics {
private int x;
public Mechanics() {
this.x = 1; //initialize x in the constructor
}
public int returnX() {
return this.x;
}
}
This is just as well, because with the behavior that you are expecting, any local variable you declare inside any member method of a class (including the constructor) would turn into a field of the owning class. This is a recipe for anarchy.
X is local variable inside constructor, and it doesn't exist after constructor finished it's work. Your code will not compile.
"this" is just a reference to object of this class. Is it possible to get value of some local variable inside other method? No, no matter how You try.
You need class field, that is visible to all methods.
The scope the variable x is restricted to the constructor.
If you want access to x in returnX you could do so:
public class Mechanics {
private int x;
public Mechanics() {
this.x =1;
}
public int returnX(){
return this.x;
}
}

'this' prefix in Java?

Does the this prefix for accessing member variables exist in Java?
Here is my HelloWorld code:
public class HelloWorld {
public static int x = 0;
public static void main(String[] args) {
HelloWorld.x = 45;
System.out.println(HelloWorld.x);
}
}
The above code works with/without the class name prefixing the variable x. However, if i try: this.x = 45; or this->x = 45; I receive an error:
non-static variable this cannot be referenced from a static context
I understand member variables can be accessed without the HelloWorld (class name) prefix, like I have done. But, I want to know if the this prefix exists in Java, how do I use it?
EDIT:
Also, could you provide an example where this is appropriate?
duffymo & byte - I greatly appreciate your help. Thanks.
Java has this as a prefix, but it's a reference to the current instance.
Static methods and attributes are associated with a class, not an instance, so you can't use this inside a static method.
public class HelloWorld {
public int x = 0; // note: now it's an instance attribute
public static void main(String[] args) {
HelloWorld hw = new HelloWorld();
System.out.println(hw.x);
}
public int getX() { return this.x; }
public void setX(int x) { this.x = x; }
}
You're attempting to use 'this' to refer to a static, not an instance variable. 'this' is only used to refer to the instance variables of an instantiated object of this class. You cannot use 'this' to refer to static variables on a class.
When you use 'this' you are saying "I want to refer to the variables of this particular instantiation of this class". A static on the other hand is always going to be the same variable for the class, irrespective of instantiation.
In addition the correct syntax for referring to an instance variable is by the dot operator:
this.x = 42; //correct
this->x = 42; //will not compile as its not valid Java
So essentially what you're after is something like the following:
public class Foo {
private int x;
public void setX(int x) {
this.x = x;
}
public int getX() {
return this.x;
}
}
public class HelloWorld {
public static void main(String[] args)
{
Foo foo = new Foo();
foo.setX(45);
System.out.println(foo.getX());
}
}
Remove the static modifier from your variable and then try it with this. Here is the difference:
Static variables exist only once in the whole program. No matter where you are, you could refer to HelloWorld.x and it would always be the same thing. That means, as you've declared it, anyone can modify it too, which may or may not be a good thing.
Member variables (not declared with static) are local to an instance of a class, which means you have to have created an instance with new before you can use it. However, every time you use new to create a new instance of that class, its non-static fields will be different. That is why you have to use this or, if in a different class, a reference to a specific instance in order to access them.
A clarification:
in getter methods it's not necessary to use the keyword this (as it's been shown in other answers). If you're new to Java this will introduce you to variable scopes (local variables vs instance variables). In other words the following works perfectly:
public class Foo {
private int x;
public void setX(int x) {
this.x = x; //Here the keywork this is necessary!
}
public int getX() {
return x; //in this case the 'x' can only be instance variable
}
}
There is also another important use of this for invoking constructors defined in the same class (You might want to check the keyword 'super' as well). Check the following:
public class HelloWorld {
public static void main(String[] args) {
Foo foo1 = new Foo();
Foo foo2 = new Foo(3, 4, 5);
System.out.println("Foo1:\n" + foo1);
System.out.println("Foo2:\n" + foo2);
}
}
class Foo {
private int x, y, z;
public Foo() {
this(-1, -1);
}
public Foo(int x, int y) {
this.x = x;
this.y = y;
}
public Foo(int x, int y, int z) {
this(x, y);
this.z = z;
}
#Override
public String toString() {
return "x= " + x + "\ny= " + y + "\nz= " + z + "\n";
}
}
Enjoy!
You can only use "this" from within an object instance.
"static", by definition, is OUTSIDE of ANY object.
Here's an excellent link in the Java documentation:
http://download.oracle.com/javase/tutorial/java/javaOO/classvars.html
'Hope that helps!
for static variables, use ClassName (like you did). For instance (non-static) variables, use this.variableName
you can use it to access instance variables and methods, you are getting this error because you are using this to access static variables.
and also ... java doesn't have =>, in java you use the .
objectName.variableName = newValue
Use this for getters/setters/constructors.
For example.
class Test {
int x;
int y;
public void Test(int x, int y) {
this.x=x;
this.y=y;
}
public void setX(int x) {
this.x=x;
}
}

defer final value to subclass java

I have a question similar to In Java, why can't I declare a final member (w/o initializing it) in the parent class and set its value in the subclass? How can I work around? but which requires a different solution. As in the above case, I want to declare a variable to be Final in the superclass, but I want the subclass to give it the value. What makes my problem different though is that I don't want the value passed in to the subclass, I want the subclass to 'know' its value, so the above solution doesn't work for me. Then I tried to do this:
public class Superclass{
public final int x;
public Superclass(int x){
this.x = x;
}
}
public class Subclass extends Superclass{
public Subclass(){
x = 1;
super(x);
}
}
...which didn't work (the call to super() must be on the first line :/ ). But this is basically the behavior that I want. Is there a good way to do this? Thanks!
You could do
super(1);
so instead of setting x, you are passing the value.
An alternative to the one above:
class Superclass{
public final int x;
public Superclass(int x){
this.x = x;
}
public static Superclass createNew(Integer y) {
return new Superclass(y);
}
public void print() {
System.out.println(this.x);
}
}
class Subclass extends Superclass{
public Subclass(int x) {
super(process(x));
}
public static Integer process(Integer y) {
if (y < 100)
y += 100;
return y;
}
}
I don't have a java compiler handy, but you're attempting to set x = 1 twice in this code.
x = 1;
And
super(x); //==> this.x = x
Do as #Kal said and do super(1), as x = 1 won't work.

Categories