Global variables and constructor(Java) - java

When are variables at the top of the class initialized in comparison to the constructor?
Sorry, this is what I meant:
public class aClass {
private int num;
public aClass {...}

Default values (null for object fields, 0 etc. for primitive fields`) are technically never explicitly assigned as far as the emitted bytecode is concerned. (This is done "internally" during object instantiation, before any initializer/constructor code runs.)
Explicit initializer code for instance fields is "copied" at the start of every constructor, after a superclass constructor call (if there is any) in the class by the compiler. The code sample:
class Foo {
int bar = 123;
public Foo() {
// ...
}
public Foo(int bar) {
this.bar = bar;
// ...
}
}
is compiled into bytecode equivalent to:
class Foo {
int bar;
public Foo() {
this.bar = 123;
// ...
}
public Foo(int bar) {
this.bar = 123;
this.bar = bar;
// ...
}
}
Same goes for initializer blocks. This means these variables get initialised before any normal constructor code executes.

Members defined with values are initialized in the constructor, just like any other members. But it's not exactly the constructor you wrote; Java changes each constructor behind the scenes by inserting member initializers and initializer blocks in the beginning of it. You could view it as the members getting initialized just before the constructor, if you want to view it temporally.

Effectively, you can consider them initialized before your constructor gets called. So if you have:
class Dog {
private String voice = "woof";
public Dog() {
System.out.println(voice);
}
}
You'll get "woof" printed to the console successfully, rather than null.

Related

Class initialization trouble: static variables are null when accessed [duplicate]

I'm running into a problem when I compile my code. When I compile my code foo2.var returns null in class foo and I can't seem to figure out why. Is there something wrong in how I'm doing the static initialization in the foo2 class to cause foo2.var to be null in the foo class?
Any help is appreciated.
public class foo extends bar {
public final static String blah = foo2.var;
...
}
public abstract class bar {
...
}
public class foo2 extends bar {
public final static String var;
static {
var = "newstring";
}
...
}
Null pointer error on the foo2.var line in this example.
Accessing a static field (whose value is not a compile-time-constant expression) will trigger initialization of the class declaring that field, during which which the static initializers are executed. However, initialization is only guaranteed to have completed by the time the field is read if there is no cyclic dependency among initializers.
For instance, if you run the program
class Bar {
static final long bar;
static {
System.out.println("Assigning bar");
bar = Foo.foo;
}
}
class Foo extends Bar {
static final long foo;
static {
System.out.println("Assigning foo");
foo = 1;
}
}
public class Test {
public static void main(String[] args) {
new Foo();
System.out.println(Bar.bar);
}
}
you get the following output:
Assigning bar
Assigning foo
0
1
because to create a new instance of Foo, Foo.class is initialized, which first initializes its super class Bar.class, which reads the field of Foo.class, but Foo.class is already being initialized. The Java Language Specification mandates in section 12.4.2, step 3, that such a recursive initialization completes immediately, i.e. the caller will see the class in a partially initialized state. That is, Foo.foo is unassigned at the time it is read, and therefore still contains the default value of 0. That value is assigned to Bar.bar, completing initialization of Bar.class. Then, initialization of Foo.class is resumed by running the initializer, which sets Foo.foo to 1.
Practically speaking, you might wish to review the dependencies of your classes and structure your program such that there are no cyclic dependencies among initializers.
You have not specified a type for var try public final static String VAR;
and then why not just
public class foo2 extends bar {
public final static String var = "newstring";
var doesn't have a type. Also constants in Java are uppercase by convention. Make it:
public class Foo2 {
public final static String VAR;
static {
VAR = "newstring";
}
...
}
You are missing a type for var, change that line to the following:
public final static String VAR;
Specify var type.
Also, by coding convention class names should be written in CamelCase and constants, UNDERSCORED_CAPS
public class Foo2 {
public final static VAR = "newstring"; // why not?
...
}
Also, you may shadow foo2 class by some variable. Check your imports. Because class static field reference cannot produce NPE!

Java Access Modifier Best Practice

This may seem a basic question, but I'd like to get this right.
I have a Class 'AWorld'. Within that class, I have a method that draws a border, depending on the map size set by the user.
If the variable 'mapSize' is private, but I want to access it's value from within the same class, is it more appropriate to reference it directly, or use a getter method.
The code below should explain what I'm wanting to know.
package javaFX;
public class AWorld {
//initialized later
AWorld newWorld;
private int mapSize = 20;
public int getMapSize()
{
return mapSize;
}
public void someMethod()
{
int var = newWorld.mapSize; //Do I reference 'mapSize' using this...
}
// Or...
public void someOtherMethod()
{
int var = newWorld.getMapSize(); //Or this?
}
public static void main(String[] args) {}
}
Either of those is ok since you're getting a primitive field. If the get method does another operation before returning the data e.g. performing a math operation on the value, then it would be better to use it rather than calling the field directly. This is specially meant when using proxy/decorator pattern on your classes.
Here's an example of the second statement from above:
//base class to be decorated
abstract class Foo {
private int x;
protected Foo foo;
public int getX() { return this.x; }
public void setX(int x) { this.x = x; }
public Foo getFoo() { return this.foo; }
//method to prove the difference between using getter and simple value
public final void printInternalX() {
if (foo != null) {
System.out.println(foo.x);
System.out.println(foo.getX());
}
}
}
//specific class implementation to be decorated
class Bar extends Foo {
#Override
public int getX() {
return super.getX() * 10;
}
}
//decorator
class Baz extends Foo {
public Baz(Foo foo) {
this.foo = foo;
}
}
public class Main {
public static void main(String[] args) {
Foo foo1 = new Bar();
foo1.setX(10);
Foo foo2 = new Bar(foo1);
//here you see the difference
foo2.printInternalX();
}
}
Output:
10
100
You better dereference it directly.
The point of the private modifier is not to expose internal implementation to other classes. These other classes will use the getter method to get the value of the private property.
In your own class, there is no point on using the getter. Worse, someone may have overridden that method in a class that extends your class, and the getter may perform something that you do not expect
IMHO, if you are referencing a field of the current instance the general rule is to access the field directly with mapSize or this.mapSize.
If you are referencing a value from a different instance (be it of the same class or a different class, I would use the getter method). I believe this would lead to simpler refactoring. It also maintains the contract that any other instance gets the field value via the getter which allows for additional functionality in the getter.

Constructor with and without any statement

Sometimes in a constructor, no statement is given. What does that indicate? For example if i create a class CIRCLE, then inside the class i write CIRCLE() {}, that is nothing is written inside. Can anyone explain it?
If your question is "why would anyone write such a constructor", then the answer is that the no-args default constructor only exists if no other constructor is specified.
Consider the following class.
class Foo {
int x;
}
As written, someone could write the following code to construct Foo.
Foo foo = new Foo();
However, now suppose I added a constructor which takes arguments.
class Foo {
int x;
public Foo(int x) {
this.x = x;
}
}
Now, suddenly, Foo foo = new Foo(); no longer works. To restore it, I must add the empty constructor again.
class Foo {
int x;
public Foo(int x) {
this.x = x;
}
public Foo() { }
}
Now, What if there are no other constructors that take arguments?
In that case, it is generally as the other answers suggest, to restrict access to constructing the class.
In the following definition of Foo, nobody is allowed to construct Foo. Perhaps Foo is meant only as a static class.
class Foo {
int x;
private Foo() { }
}
In the protected case, only subclasses can construct Foo.
class Foo {
int x;
protected Foo() { }
}
If there is no code in the constructor, chances are, it was declared to change the access to the constructor. By default, constructors are public. If you wanted to make it private, protected or package-private, you must explicitly declare it and manually change the modifier.
class Example {
public static void main(String[] args) {
new Demo(); //this is currently allowed
}
}
class Demo {
}
In order to prevent the creation of a Demo object within Example, we could declare Demo's constructor amd make it private:
class Demo {
private Demo() { }
}
Another reason could be that the class has a constructor that requires parameters. If so, you must explicitly declare the no-arg constructor to be able to use it.
If nothing is written, then when a new Object of that type is created, nothing 'extra' is done, whereas if in the constructor has code in, it does something.
For example, the following consructor for a class called 'Bank' assigns the argument 'name' to the field 'bankName', then instantiates a Terminal and 2 bank accounts:
private static final int INITIAL_BALANCE = 200;
public Bank( String name )
{
bankName = name;
atm = new Terminal();
account1 = new BankAccount( INITIAL_BALANCE );
account2 = new BankAccount( INITIAL_BALANCE );
}
It's a default constructor. For instance if you go:
Circle circle = new Circle();
You are then calling the default constructor. When you go ... Circle() that is a call to the default constructor, the one with no parameters.
The point of this is just to 'construct' an object or instantiate a class (instantiate just means create an object which is an instance of the class) with no additional information i.e. parameters.
This would generally be used to initialize fields to their default values, like so:
public Circle() {
this.x = 0;
this.y = 0;
}

Is passing object to constructor pass by reference [duplicate]

This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 9 years ago.
Suppose I have a class and constructor called TestClass.
public class TestClass {
Foo foo;
public TestClass(Foo foo) {
this.foo = foo;
}
}
Here, the constructor accepts an object which is an instance of class Foo. Suppose my static void main(String[] args) does the following, completely separate from any TestClass;
(1) Instantiate foo
(2) Pass instance foo to TestClass constructor
(3) Change the internal state of foo
After step (3), will the foo within my instance of TestClass also have its state changed?
It is not passed by reference. Rather, it is passed by value of the reference, which is a subtle but important distinction.
After you mutate foo in the rest of your main() method, the foo field will also exhibit these mutations, as you state, since both variables point to the same instance. However, if you reassign foo to something new, the foo field will not be changed. This would not be true if foo were truly passed by reference. In short, everything is passed by value in Java; it just so happens that objects are dealt with by reference, and so the values of these references are passed.
I'll try to illustrate this with an example. Consider the following class:
class A {
public int n;
public A(int n) {
this.n = n;
}
}
and the following method:
public static void mutate(A a) {
a.n = 42;
}
Now we can have something like this:
A a = new A(0);
A.mutate(a);
System.out.println(a.n);
42
We can see that the state of a was changed in mutate(). Now let's modify the static method:
public static void mutate(A a) {
a = new A(42);
}
and try again:
A a = new A(0);
A.mutate(a);
System.out.println(a.n);
0
As you can see, the state of a is unchanged. If the reference had been passed to the function, we would expect the effect of the reassignment to be evident beyond the scope of the method. Nevertheless, some reference was in fact passed, since mutating the argument caused changes outside of the method as well.
Yes, because you are assigning same object to another reference of Foo class, i.e. object is same, but being referred by two reference.
After step (3), will the foo within my instance of TestClass also have
its state changed?
Yes.
You might like to take a read through this
Updated...
Now, assuming you pass the constructor a primitive value...
public class TestClass {
int foo;
public TestClass(int foo) {
this.foo = foo;
}
public String toString() {
return "TestClass: " + foo;
}
}
public static void main(String args[]) {
int myFoo = 1;
TestClass test = new TestClass(myFoo);
myFoo += 2;
System.out.println("myFoo = " + myFoo);
System.out.println("yourFoo = " + test);
}
This will output...
myFoo = 3
yourFoo = 1
Which demonstrates the fact that changing the value of a primitive does not change the value maintained by the constructor/method.
Equally, if you change the object reference after you pass it
public class TestClass {
Foo foo;
public TestClass(Foo foo) {
this.foo = foo;
}
public Foo getFoo() {
return foo;
}
}
public static void main(String args[]) {
Foo myFoo = new Foo();
TestClass test = new TestClass(myFoo);
myFoo = new Foo();
System.out.println("myFoo == yourFoo = " + myFoo.equals(test.getFoo()));
}
Will output
myFoo == yourFoo = false
As the object references are not the same.

Confused with this simple example of polymorphism

Please have a look at this code :
class Foo {
public int a;
public Foo() {
a = 3;
}
public void addFive() {
a += 5;
}
public int getA() {
System.out.println("we are here in base class!");
return a;
}
}
public class Polymorphism extends Foo{
public int a;
public Poylmorphism() {
a = 5;
}
public void addFive() {
System.out.println("we are here !" + a);
a += 5;
}
public int getA() {
System.out.println("we are here in sub class!");
return a;
}
public static void main(String [] main) {
Foo f = new Polymorphism();
f.addFive();
System.out.println(f.getA());
System.out.println(f.a);
}
}
Here we assign reference of object of class Polymorphism to variable of type Foo, classic polmorphism. Now we call method addFive which has been overridden in class Polymorphism. Then we print the variable value from a getter method which also has been overridden in class Polymorphism. So we get answer as 10. But when public variable a is SOP'ed we get answer 3!!
How did this happen? Even though reference variable type was Foo but it was referring to object of Polymorphism class. So why did accessing f.a not result into value of a in the class Polymorphism getting printed? Please help
You're hiding the a of Polymorphism - you should actually get a compiler warning for that. Therefore those are two distinct a fields. In contrast to methods fields cannot be virtual. Good practice is not to have public fields at all, but only methods for mutating private state (encapsulation).
If you want to make it virtual, you need to make it as a property with accessor methods (e.g. what you have: getA).
This is due to the fact that you can't override class varibles. When accessing a class variable, type of the reference, rather than the type of the object, is what decides what you will get.
If you remove the redeclaration of a in the subclass, then I assume that behaviour will be more as expected.

Categories