Java output explanation [duplicate] - java

Consider the int a variables in these classes:
class Foo {
public int a = 3;
public void addFive() { a += 5; System.out.print("f "); }
}
class Bar extends Foo {
public int a = 8;
public void addFive() { this.a += 5; System.out.print("b " ); }
}
public class test {
public static void main(String [] args){
Foo f = new Bar();
f.addFive();
System.out.println(f.a);
}
}
I understand that the method addFive() have been overridden in the child class, and in class test when the base class reference referring to child class is used to call the overridden method, the child class version of addFive is called.
But what about the public instance variable a? What happens when both base class and derived class have the same variable?
The output of the above program is
b 3
How does this happen?

There are actually two distinct public instance variables called a.
A Foo object has a Foo.a variable.
A Bar object has both Foo.a and Bar.a variables.
When you run this:
Foo f = new Bar();
f.addFive();
System.out.println(f.a);
the addFive method is updating the Bar.a variable, and then reading the Foo.a variable. To read the Bar.a variable, you would need to do this:
System.out.println(((Bar) f).a);
The technical term for what is happening here is "hiding". Refer to the JLS section 8.3, and section 8.3.3.2 for an example.
Note that hiding also applies to static methods with the same signature.
However instance methods with the same signature are "overridden" not "hidden", and you cannot access the version of a method that is overridden from the outside. (Within the class that overrides a method, the overridden method can be called using super. However, that's the only situation where this is allowed. The reason that accessing overridden methods is generally forbidden is that it would break data abstraction.)
The recommended way to avoid the confusion of (accidental) hiding is to declare your instance variables as private and access them via getter and setter methods. There are lots of other good reasons for using getters and setters too.
It should also be noted that: 1) Exposing public variables (like a) is generally a bad idea, because it leads to weak abstraction, unwanted coupling, and other problems. 2) Intentionally declaring a 2nd public a variable in the child class is a truly awful idea.

From JLS
8.3.3.2 Example: Hiding of Instance Variables This example is similar to
that in the previous section, but uses
instance variables rather than static
variables. The code:
class Point {
int x = 2;
}
class Test extends Point {
double x = 4.7;
void printBoth() {
System.out.println(x + " " + super.x);
}
public static void main(String[] args) {
Test sample = new Test();
sample.printBoth();
System.out.println(sample.x + " " +
((Point)sample).x);
}
}
produces the output:
4.7 2
4.7 2
because the declaration of x in class
Test hides the definition of x in
class Point, so class Test does not
inherit the field x from its
superclass Point. It must be noted,
however, that while the field x of
class Point is not inherited by class
Test, it is nevertheless implemented
by instances of class Test. In other
words, every instance of class Test
contains two fields, one of type int
and one of type double. Both fields
bear the name x, but within the
declaration of class Test, the simple
name x always refers to the field
declared within class Test. Code in
instance methods of class Test may
refer to the instance variable x of
class Point as super.x.
Code that uses a field access
expression to access field x will
access the field named x in the class
indicated by the type of reference
expression. Thus, the expression
sample.x accesses a double value, the
instance variable declared in class
Test, because the type of the variable
sample is Test, but the expression
((Point)sample).x accesses an int
value, the instance variable declared
in class Point, because of the cast to
type Point.

In inheritance, a Base class object can refer to an instance of Derived class.
So this is how Foo f = new Bar(); works okay.
Now when f.addFive(); statement gets invoked it actually calls the 'addFive() method of the Derived class instance using the reference variable of the Base class. So ultimately the method of 'Bar' class gets invoked. But as you see the addFive() method of 'Bar' class just prints 'b ' and not the value of 'a'.
The next statement i.e. System.out.println(f.a) is the one that actually prints the value of a which ultimately gets appended to the previous output and so you see the final output as 'b 3'. Here the value of a used is that of 'Foo' class.
Hope this trick execution & coding is clear and you understood how you got the output as 'b 3'.

Here F is of type Foo and f variable is holding Bar object but java runtime gets the f.a from the class Foo.This is because in Java variable names are resolved using the reference type and not the object which it is referring.

Related

What happens to variables/objects in inner classes of function objects?

I have a function multi2 which returns inner class Inner as an Object.
What happens to a - where is it saved and how can I access it?
public class C {
private static Object multi2(final int a) {
class Inner {
public int hashCode() {
return 2*a;
}
}
return new Inner(); // What happens to a?
// Who allocates a?
// Can I Access a?
}
public static void main(String[] args) {
Object o = multi2(6);
System.out.println("o.hashCode() = " + o.hashCode());
o = multi2(4);
System.out.println("o.hashCode() = " + o.hashCode());
}
}
What happens at the implementation level is that a copy of the value of a is saved in a synthetic instance variable declared in the compiled version of the C.Inner class.
The value of a is passed to the compiled Inner constructor via an extra parameter.
The C.Inner.hashCode method uses the value of the synthetic variable. Accessing a in the source code of Inner.hashCode is transformed into accessing the corresponding synthetic variable in the compiled code.
The variable in the outer scope must be final1. The synthetic variable must be final2 in the Inner class. This maintains the illusion that (potentially) multiple instances of the Inner class are seeing the same a variable. (They aren't, but since the variable(s) can't be changed, it is not possible for the code of the inner class to tell the difference.)
If you use javap to look at the bytecodes for the compiled example, you will see the mechanisms used to implement this in the outer and the inner classes.
1 - or effectively final from Java 8 onwards.
2 - If a could be mutated by an Inner method, then two Inner instances with the same outer class need to share a mutable variable whose lifetime is (now) longer than the stackframe for a multi2 call. That entails somehow turning a from stack variable into something that lives on the heap. It would be expensive and complicated.
You have defined the class Inner inside the function so the scope of the class will be
restricted with in the method. And your function is static so it will be live as long as the class definition is loaded. You have override the hashCode function inside the InnerClass so every time you are calling the multi2(param) you are creating the hashCode for the instance of InnerClass and returning the instance of the InnerClass.
So as for you questions, please correct me if i am wrong.
What happens to a ?
a is with in the scope of your static method, so it will be live as long as the class definition is loaded.
Who allocates a?
scope of a is restricted inside the static method and static method does not require instance to access it but as for the static method/variable allocation, i think it depends on JVM.
Can I Access a?
No you cannot access a from outside you static method, it is restricted with in your static method.
Since the "a" is a local parameter, you could use a different approach to read the "a" value:
public class C {
public static Object multi2(final int a) {
return new Inner(a);
}
public static void main(String[] args) {
Object o = multi2(6);
System.out.println("o.hashCode() = " + o.hashCode());
System.out.println("o.getA() = " + ((Inner) o).getA());
o = multi2(4);
System.out.println("o.hashCode() = " + o.hashCode());
System.out.println("o.getA() = " + ((Inner) o).getA());
}
}
class Inner{
public int valueA;
public Inner(int a)
{
valueA = a;
}
public int getA() {
return valueA;
}
public int hashCode() {
return 2*valueA;
}
}
I wanted to know what was actually happening, so I compiled your code and looked at the bytecode output.
Basically what happens is the compiler adds in a constructor to your class 'Inner'. It also adds a single parameter to that constructor which takes 'a'. If your multi2() method was NOT static then there would probably also be a parameter to take 'this' where 'this' is the instance of 'C' that multi2() is executing on. BUT since we're in static context, there is no 'this'.
The compiler adds a private final field to your class 'Inner' and sets that private field using the value passed via the constructor. The compiler also converts
new Inner()
into
new Inner(a)
Hashcode then accesses the private field containing the value for a.
If 'a' was an object instead of a primitive, then it would be the same way, but a reference would be passed through instead of an actual number value.
How do you access this variable? Well you access it with reflections, but there are many problems:
1) You don't know the name of the field made by the compiler, so you can only get the name by looking at the bytecode. Don't trust decompilers as they might change the name. You gotta look at the bytecode yourself to find out.
2) The compiler probably marks the field as final, which means even if you can get reflections to access the field for you, you won't be able to update it.
3) It is entirely up to the compiler to figure out field names. Field names could change between builds depending on the compiler and it's mood.
Inner is a so called local class. a is a parameter passed to the method multi2 and accessable within that scope. Outside of that method, you cannot access a.

Objects With Multiple Fields of the Same Name [duplicate]

I am studying overriding member functions in Java and thought about experimenting with overriding member variables.
So, I defined classes
public class A{
public int intVal = 1;
public void identifyClass()
{
System.out.println("I am class A");
}
}
public class B extends A
{
public int intVal = 2;
public void identifyClass()
{
System.out.println("I am class B");
}
}
public class mainClass
{
public static void main(String [] args)
{
A a = new A();
B b = new B();
A aRef;
aRef = a;
System.out.println(aRef.intVal);
aRef.identifyClass();
aRef = b;
System.out.println(aRef.intVal);
aRef.identifyClass();
}
}
The output is:
1
I am class A
1
I am class B
I am not able to understand why when aRef is set to b intVal is still of class A?
When you make a variable of the same name in a subclass, that's called hiding. The resulting subclass will now have both properties. You can access the one from the superclass with super.var or ((SuperClass)this).var. The variables don't even have to be of the same type; they are just two variables sharing a name, much like two overloaded methods.
Variables are not polymorphic in Java; they do not override one another.
There is no polymorphism for fields in Java.
Variables decision happens at a compile time so always Base Class variables (not child’s inherited variables) will be accessed.
So whenever upcasting happens always remember
1) Base Class variables will be accessed.
2) Sub Class methods(overridden methods if overriding happened else inherited methods as it is from parent) will be called.
Variables are resolved compile-time, methods run-time. The aRef is of type A, therefore aRef.Intvalue is compile-time resolved to 1.
OverRiding Concept in Java
Functions will override depends on object type and variables will accessed on reference type.
Override Function: In this case suppose a parent and child class both have same name of function with own definition. But which function will execute it depends on object type not on reference type on run time.
For e.g.:
Parent parent=new Child();
parent.behaviour();
Here parent is a reference of Parent class but holds an object of Child Class so that's why Child class function will be called in that case.
Child child=new Child();
child.behaviour();
Here child holds an object of Child Class, so the Child class function will be called.
Parent parent=new Parent();
parent.behaviour();
Here parent holds the object of Parent Class, so the Parent class function will be called.
Override Variable: Java supports overloaded variables. But actually these are two different variables with same name, one in the parent class and one in the child class. And both variables can be either of the same datatype or different.
When you trying to access the variable, it depends on the reference type object, not the object type.
For e.g.:
Parent parent=new Child();
System.out.println(parent.state);
The reference type is Parent so the Parent class variable is accessed, not the Child class variable.
Child child=new Child();
System.out.println(child.state);
Here the reference type is Child, so the Child class variable is accessed not the Parent class variable.
Parent parent=new Parent();
System.out.println(parent.state);
Here the reference type is Parent, so Parent class variable is accessed.
From JLS Java SE 7 Edition §15.11.1:
This lack of dynamic lookup for field accesses allows programs to be run efficiently with straightforward implementations. The power of late binding and overriding is available, but only when instance methods are used.
Answers from Oliver Charlesworth and Marko Topolnik are correct, I would like to elaborate a little bit more on the why part of the question:
In Java class members are accessed according the type of the reference and not the type of the actual object. For the same reason, if you had a someOtherMethodInB() in class B, you wouldn't be able to access it from aRef after aRef = b is run. Identifiers (ie class, variable, etc names) are resolved at compile time and thus the compiler relies on the reference type to do this.
Now in your example, when running System.out.println(aRef.intVal); it prints the value of intVal defined in A because this is the type of the reference you use to access it. The compiler sees that aRef is of type A and that's the intVal it will access. Don't forget that you have both fields in the instances of B. JLS also has an example similar to yours, "15.11.1-1. Static Binding for Field Access" if you want to take a look.
But why do methods behave differently? The answer is that for methods, Java uses late binding. That means that at compile time, it finds the most suitable method to search for during the runtime. The search involves the case of the method being overridden in some class.
I hope this can help:
public class B extends A {
// public int intVal = 2;
public B() {
super();
super.intVal = 2;
}
public void identifyClass() {
System.out.println("I am class B");
}
}
So overriding variable of base class is not possible, but base class variable value can be set (changed) from constructor of inherited class.
This is called variable hiding. When you assign aRef = b; , aRef has two intVal, 1 is named just intVal another is hidden under A.intVal (see debugger screenshot), Because your variable is of type class A , even when you print just intVal java intelligently picks up A.intVal.
Answer 1: One way of accessing child class's intVal is System.out.println((B)aRef.intVal);
Answer 2: Another way of doing it is Java Reflection because when you use reflection java cant intelligently pickup hidden A.intVal based on Class type, it has to pick up the variable name given as string -
import java.lang.reflect.Field;
class A{
public int intVal = 1;
public void identifyClass()
{
System.out.println("I am class A");
}
}
class B extends A
{
public int intVal = 2;
public void identifyClass()
{
System.out.println("I am class B");
}
}
public class Main
{
public static void main(String [] args) throws Exception
{
A a = new A();
B b = new B();
A aRef;
aRef = a;
System.out.println(aRef.intVal);
aRef.identifyClass();
aRef = b;
Field xField = aRef.getClass().getField("intVal");
System.out.println(xField.get(aRef));
aRef.identifyClass();
}
}
Output -
1
I am class A
2
I am class B
Well, I hope u got the answer. If not, you can try seeing in the debug mode. the subclass B has access to both the intVal. They are not polymorphic hence they are not overriden.
If you use B's reference you will get B's intVal. If you use A's reference , you will get A's intVal. It's that simple.
As per the Java specifications, the instance variables are not overridden from a super class by a sub class when it is extended.
Hence the variable in the sub class only can be seen as one sharing the same name.
Also when the constructor of A is called during the instance creation of B the variable (intVal) is initialized and hence the output.
It is because when you assign b to aRef, it is resolved, leading aRef to just be of class A. This means that aRef does not have access to any of class B's fields or methods. If you call for intVal instead by using b.intVal, you will get 2.
Java has a feather of encapsulation means it tightly binds the property and the behavior of an object. so only via a class reference we can call it's behavior to change it's property.
and in inheritance only method overrides so that it can affects only it's property.
As Many users have already pointed out, this is not polymorphism. Polymorphism only applies to methods(functions).
Now as to why the value of the intVal of class A is printed, this happens because as you can see the reference aRef is of type A.
I can see why you are confused by it. By the same procedure you have accessed the overridden methods for ex. the method identifyClass() but the not the variables which directly proves the first line that I have written .
Now in order to access the variable you can do ((Superclass)c).var
Note here that the Superclass can be many levels up for example
A<-B<-C. That is C extends B and B extends A. If you wanted the value of var of A then you could have done ((A)c).var .
EDIT: as one of the users have pointed out this 'trick' does not apply to static methods, because they are static.

Accessing members of class after Upcasting in Java [duplicate]

I am studying overriding member functions in Java and thought about experimenting with overriding member variables.
So, I defined classes
public class A{
public int intVal = 1;
public void identifyClass()
{
System.out.println("I am class A");
}
}
public class B extends A
{
public int intVal = 2;
public void identifyClass()
{
System.out.println("I am class B");
}
}
public class mainClass
{
public static void main(String [] args)
{
A a = new A();
B b = new B();
A aRef;
aRef = a;
System.out.println(aRef.intVal);
aRef.identifyClass();
aRef = b;
System.out.println(aRef.intVal);
aRef.identifyClass();
}
}
The output is:
1
I am class A
1
I am class B
I am not able to understand why when aRef is set to b intVal is still of class A?
When you make a variable of the same name in a subclass, that's called hiding. The resulting subclass will now have both properties. You can access the one from the superclass with super.var or ((SuperClass)this).var. The variables don't even have to be of the same type; they are just two variables sharing a name, much like two overloaded methods.
Variables are not polymorphic in Java; they do not override one another.
There is no polymorphism for fields in Java.
Variables decision happens at a compile time so always Base Class variables (not child’s inherited variables) will be accessed.
So whenever upcasting happens always remember
1) Base Class variables will be accessed.
2) Sub Class methods(overridden methods if overriding happened else inherited methods as it is from parent) will be called.
Variables are resolved compile-time, methods run-time. The aRef is of type A, therefore aRef.Intvalue is compile-time resolved to 1.
OverRiding Concept in Java
Functions will override depends on object type and variables will accessed on reference type.
Override Function: In this case suppose a parent and child class both have same name of function with own definition. But which function will execute it depends on object type not on reference type on run time.
For e.g.:
Parent parent=new Child();
parent.behaviour();
Here parent is a reference of Parent class but holds an object of Child Class so that's why Child class function will be called in that case.
Child child=new Child();
child.behaviour();
Here child holds an object of Child Class, so the Child class function will be called.
Parent parent=new Parent();
parent.behaviour();
Here parent holds the object of Parent Class, so the Parent class function will be called.
Override Variable: Java supports overloaded variables. But actually these are two different variables with same name, one in the parent class and one in the child class. And both variables can be either of the same datatype or different.
When you trying to access the variable, it depends on the reference type object, not the object type.
For e.g.:
Parent parent=new Child();
System.out.println(parent.state);
The reference type is Parent so the Parent class variable is accessed, not the Child class variable.
Child child=new Child();
System.out.println(child.state);
Here the reference type is Child, so the Child class variable is accessed not the Parent class variable.
Parent parent=new Parent();
System.out.println(parent.state);
Here the reference type is Parent, so Parent class variable is accessed.
From JLS Java SE 7 Edition §15.11.1:
This lack of dynamic lookup for field accesses allows programs to be run efficiently with straightforward implementations. The power of late binding and overriding is available, but only when instance methods are used.
Answers from Oliver Charlesworth and Marko Topolnik are correct, I would like to elaborate a little bit more on the why part of the question:
In Java class members are accessed according the type of the reference and not the type of the actual object. For the same reason, if you had a someOtherMethodInB() in class B, you wouldn't be able to access it from aRef after aRef = b is run. Identifiers (ie class, variable, etc names) are resolved at compile time and thus the compiler relies on the reference type to do this.
Now in your example, when running System.out.println(aRef.intVal); it prints the value of intVal defined in A because this is the type of the reference you use to access it. The compiler sees that aRef is of type A and that's the intVal it will access. Don't forget that you have both fields in the instances of B. JLS also has an example similar to yours, "15.11.1-1. Static Binding for Field Access" if you want to take a look.
But why do methods behave differently? The answer is that for methods, Java uses late binding. That means that at compile time, it finds the most suitable method to search for during the runtime. The search involves the case of the method being overridden in some class.
I hope this can help:
public class B extends A {
// public int intVal = 2;
public B() {
super();
super.intVal = 2;
}
public void identifyClass() {
System.out.println("I am class B");
}
}
So overriding variable of base class is not possible, but base class variable value can be set (changed) from constructor of inherited class.
This is called variable hiding. When you assign aRef = b; , aRef has two intVal, 1 is named just intVal another is hidden under A.intVal (see debugger screenshot), Because your variable is of type class A , even when you print just intVal java intelligently picks up A.intVal.
Answer 1: One way of accessing child class's intVal is System.out.println((B)aRef.intVal);
Answer 2: Another way of doing it is Java Reflection because when you use reflection java cant intelligently pickup hidden A.intVal based on Class type, it has to pick up the variable name given as string -
import java.lang.reflect.Field;
class A{
public int intVal = 1;
public void identifyClass()
{
System.out.println("I am class A");
}
}
class B extends A
{
public int intVal = 2;
public void identifyClass()
{
System.out.println("I am class B");
}
}
public class Main
{
public static void main(String [] args) throws Exception
{
A a = new A();
B b = new B();
A aRef;
aRef = a;
System.out.println(aRef.intVal);
aRef.identifyClass();
aRef = b;
Field xField = aRef.getClass().getField("intVal");
System.out.println(xField.get(aRef));
aRef.identifyClass();
}
}
Output -
1
I am class A
2
I am class B
Well, I hope u got the answer. If not, you can try seeing in the debug mode. the subclass B has access to both the intVal. They are not polymorphic hence they are not overriden.
If you use B's reference you will get B's intVal. If you use A's reference , you will get A's intVal. It's that simple.
As per the Java specifications, the instance variables are not overridden from a super class by a sub class when it is extended.
Hence the variable in the sub class only can be seen as one sharing the same name.
Also when the constructor of A is called during the instance creation of B the variable (intVal) is initialized and hence the output.
It is because when you assign b to aRef, it is resolved, leading aRef to just be of class A. This means that aRef does not have access to any of class B's fields or methods. If you call for intVal instead by using b.intVal, you will get 2.
Java has a feather of encapsulation means it tightly binds the property and the behavior of an object. so only via a class reference we can call it's behavior to change it's property.
and in inheritance only method overrides so that it can affects only it's property.
As Many users have already pointed out, this is not polymorphism. Polymorphism only applies to methods(functions).
Now as to why the value of the intVal of class A is printed, this happens because as you can see the reference aRef is of type A.
I can see why you are confused by it. By the same procedure you have accessed the overridden methods for ex. the method identifyClass() but the not the variables which directly proves the first line that I have written .
Now in order to access the variable you can do ((Superclass)c).var
Note here that the Superclass can be many levels up for example
A<-B<-C. That is C extends B and B extends A. If you wanted the value of var of A then you could have done ((A)c).var .
EDIT: as one of the users have pointed out this 'trick' does not apply to static methods, because they are static.

Why is the field not overridden? [duplicate]

I am studying overriding member functions in Java and thought about experimenting with overriding member variables.
So, I defined classes
public class A{
public int intVal = 1;
public void identifyClass()
{
System.out.println("I am class A");
}
}
public class B extends A
{
public int intVal = 2;
public void identifyClass()
{
System.out.println("I am class B");
}
}
public class mainClass
{
public static void main(String [] args)
{
A a = new A();
B b = new B();
A aRef;
aRef = a;
System.out.println(aRef.intVal);
aRef.identifyClass();
aRef = b;
System.out.println(aRef.intVal);
aRef.identifyClass();
}
}
The output is:
1
I am class A
1
I am class B
I am not able to understand why when aRef is set to b intVal is still of class A?
When you make a variable of the same name in a subclass, that's called hiding. The resulting subclass will now have both properties. You can access the one from the superclass with super.var or ((SuperClass)this).var. The variables don't even have to be of the same type; they are just two variables sharing a name, much like two overloaded methods.
Variables are not polymorphic in Java; they do not override one another.
There is no polymorphism for fields in Java.
Variables decision happens at a compile time so always Base Class variables (not child’s inherited variables) will be accessed.
So whenever upcasting happens always remember
1) Base Class variables will be accessed.
2) Sub Class methods(overridden methods if overriding happened else inherited methods as it is from parent) will be called.
Variables are resolved compile-time, methods run-time. The aRef is of type A, therefore aRef.Intvalue is compile-time resolved to 1.
OverRiding Concept in Java
Functions will override depends on object type and variables will accessed on reference type.
Override Function: In this case suppose a parent and child class both have same name of function with own definition. But which function will execute it depends on object type not on reference type on run time.
For e.g.:
Parent parent=new Child();
parent.behaviour();
Here parent is a reference of Parent class but holds an object of Child Class so that's why Child class function will be called in that case.
Child child=new Child();
child.behaviour();
Here child holds an object of Child Class, so the Child class function will be called.
Parent parent=new Parent();
parent.behaviour();
Here parent holds the object of Parent Class, so the Parent class function will be called.
Override Variable: Java supports overloaded variables. But actually these are two different variables with same name, one in the parent class and one in the child class. And both variables can be either of the same datatype or different.
When you trying to access the variable, it depends on the reference type object, not the object type.
For e.g.:
Parent parent=new Child();
System.out.println(parent.state);
The reference type is Parent so the Parent class variable is accessed, not the Child class variable.
Child child=new Child();
System.out.println(child.state);
Here the reference type is Child, so the Child class variable is accessed not the Parent class variable.
Parent parent=new Parent();
System.out.println(parent.state);
Here the reference type is Parent, so Parent class variable is accessed.
From JLS Java SE 7 Edition §15.11.1:
This lack of dynamic lookup for field accesses allows programs to be run efficiently with straightforward implementations. The power of late binding and overriding is available, but only when instance methods are used.
Answers from Oliver Charlesworth and Marko Topolnik are correct, I would like to elaborate a little bit more on the why part of the question:
In Java class members are accessed according the type of the reference and not the type of the actual object. For the same reason, if you had a someOtherMethodInB() in class B, you wouldn't be able to access it from aRef after aRef = b is run. Identifiers (ie class, variable, etc names) are resolved at compile time and thus the compiler relies on the reference type to do this.
Now in your example, when running System.out.println(aRef.intVal); it prints the value of intVal defined in A because this is the type of the reference you use to access it. The compiler sees that aRef is of type A and that's the intVal it will access. Don't forget that you have both fields in the instances of B. JLS also has an example similar to yours, "15.11.1-1. Static Binding for Field Access" if you want to take a look.
But why do methods behave differently? The answer is that for methods, Java uses late binding. That means that at compile time, it finds the most suitable method to search for during the runtime. The search involves the case of the method being overridden in some class.
I hope this can help:
public class B extends A {
// public int intVal = 2;
public B() {
super();
super.intVal = 2;
}
public void identifyClass() {
System.out.println("I am class B");
}
}
So overriding variable of base class is not possible, but base class variable value can be set (changed) from constructor of inherited class.
This is called variable hiding. When you assign aRef = b; , aRef has two intVal, 1 is named just intVal another is hidden under A.intVal (see debugger screenshot), Because your variable is of type class A , even when you print just intVal java intelligently picks up A.intVal.
Answer 1: One way of accessing child class's intVal is System.out.println((B)aRef.intVal);
Answer 2: Another way of doing it is Java Reflection because when you use reflection java cant intelligently pickup hidden A.intVal based on Class type, it has to pick up the variable name given as string -
import java.lang.reflect.Field;
class A{
public int intVal = 1;
public void identifyClass()
{
System.out.println("I am class A");
}
}
class B extends A
{
public int intVal = 2;
public void identifyClass()
{
System.out.println("I am class B");
}
}
public class Main
{
public static void main(String [] args) throws Exception
{
A a = new A();
B b = new B();
A aRef;
aRef = a;
System.out.println(aRef.intVal);
aRef.identifyClass();
aRef = b;
Field xField = aRef.getClass().getField("intVal");
System.out.println(xField.get(aRef));
aRef.identifyClass();
}
}
Output -
1
I am class A
2
I am class B
Well, I hope u got the answer. If not, you can try seeing in the debug mode. the subclass B has access to both the intVal. They are not polymorphic hence they are not overriden.
If you use B's reference you will get B's intVal. If you use A's reference , you will get A's intVal. It's that simple.
As per the Java specifications, the instance variables are not overridden from a super class by a sub class when it is extended.
Hence the variable in the sub class only can be seen as one sharing the same name.
Also when the constructor of A is called during the instance creation of B the variable (intVal) is initialized and hence the output.
It is because when you assign b to aRef, it is resolved, leading aRef to just be of class A. This means that aRef does not have access to any of class B's fields or methods. If you call for intVal instead by using b.intVal, you will get 2.
Java has a feather of encapsulation means it tightly binds the property and the behavior of an object. so only via a class reference we can call it's behavior to change it's property.
and in inheritance only method overrides so that it can affects only it's property.
As Many users have already pointed out, this is not polymorphism. Polymorphism only applies to methods(functions).
Now as to why the value of the intVal of class A is printed, this happens because as you can see the reference aRef is of type A.
I can see why you are confused by it. By the same procedure you have accessed the overridden methods for ex. the method identifyClass() but the not the variables which directly proves the first line that I have written .
Now in order to access the variable you can do ((Superclass)c).var
Note here that the Superclass can be many levels up for example
A<-B<-C. That is C extends B and B extends A. If you wanted the value of var of A then you could have done ((A)c).var .
EDIT: as one of the users have pointed out this 'trick' does not apply to static methods, because they are static.

Difference between Static and final?

I'm always confused between static and final keywords in java.
How are they different ?
The static keyword can be used in 4 scenarios
static variables
static methods
static blocks of code
static nested class
Let's look at static variables and static methods first.
Static variable
It is a variable which belongs to the class and not to object (instance).
Static variables are initialized only once, at the start of the execution. These variables will be initialized first, before the initialization of any instance variables.
A single copy to be shared by all instances of the class.
A static variable can be accessed directly by the class name and doesn’t need any object.
Syntax: Class.variable
Static method
It is a method which belongs to the class and not to the object (instance).
A static method can access only static data. It can not access non-static data (instance variables) unless it has/creates an instance of the class.
A static method can call only other static methods and can not call a non-static method from it unless it has/creates an instance of the class.
A static method can be accessed directly by the class name and doesn’t need any object.
Syntax: Class.methodName()
A static method cannot refer to this or super keywords in anyway.
Static class
Java also has "static nested classes". A static nested class is just one which doesn't implicitly have a reference to an instance of the outer class.
Static nested classes can have instance methods and static methods.
There's no such thing as a top-level static class in Java.
Side note:
main method is static since it must be be accessible for an application to run before any instantiation takes place.
final keyword is used in several different contexts to define an entity which cannot later be changed.
A final class cannot be subclassed. This is done for reasons of security and efficiency. Accordingly, many of the Java standard library classes are final, for example java.lang.System and java.lang.String. All methods in a final class are implicitly final.
A final method can't be overridden by subclasses. This is used to prevent unexpected behavior from a subclass altering a method that may be crucial to the function or consistency of the class.
A final variable can only be initialized once, either via an initializer or an assignment statement. It does not need to be initialized at the point of declaration: this is called a blank final variable. A blank final instance variable of a class must be definitely assigned at the end of every constructor of the class in which it is declared; similarly, a blank final static variable must be definitely assigned in a static initializer of the class in which it is declared; otherwise, a compile-time error occurs in both cases.
Note: If the variable is a reference, this means that the variable cannot be re-bound to reference another object. But the object that it references is still mutable, if it was originally mutable.
When an anonymous inner class is defined within the body of a method, all variables declared final in the scope of that method are accessible from within the inner class. Once it has been assigned, the value of the final variable cannot change.
static means it belongs to the class not an instance, this means that there is only one copy of that variable/method shared between all instances of a particular Class.
public class MyClass {
public static int myVariable = 0;
}
//Now in some other code creating two instances of MyClass
//and altering the variable will affect all instances
MyClass instance1 = new MyClass();
MyClass instance2 = new MyClass();
MyClass.myVariable = 5; //This change is reflected in both instances
final is entirely unrelated, it is a way of defining a once only initialization. You can either initialize when defining the variable or within the constructor, nowhere else.
note A note on final methods and final classes, this is a way of explicitly stating that the method or class can not be overridden / extended respectively.
Extra Reading
So on the topic of static, we were talking about the other uses it may have, it is sometimes used in static blocks. When using static variables it is sometimes necessary to set these variables up before using the class, but unfortunately you do not get a constructor. This is where the static keyword comes in.
public class MyClass {
public static List<String> cars = new ArrayList<String>();
static {
cars.add("Ferrari");
cars.add("Scoda");
}
}
public class TestClass {
public static void main(String args[]) {
System.out.println(MyClass.cars.get(0)); //This will print Ferrari
}
}
You must not get this confused with instance initializer blocks which are called before the constructor per instance.
The two really aren't similar. static fields are fields that do not belong to any particular instance of a class.
class C {
public static int n = 42;
}
Here, the static field n isn't associated with any particular instance of C but with the entire class in general (which is why C.n can be used to access it). Can you still use an instance of C to access n? Yes - but it isn't considered particularly good practice.
final on the other hand indicates that a particular variable cannot change after it is initialized.
class C {
public final int n = 42;
}
Here, n cannot be re-assigned because it is final. One other difference is that any variable can be declared final, while not every variable can be declared static.
Also, classes can be declared final which indicates that they cannot be extended:
final class C {}
class B extends C {} // error!
Similarly, methods can be declared final to indicate that they cannot be overriden by an extending class:
class C {
public final void foo() {}
}
class B extends C {
public void foo() {} // error!
}
static means there is only one copy of the variable in memory shared by all instances of the class.
The final keyword just means the value can't be changed. Without final, any object can change the value of the variable.
final -
1)When we apply "final" keyword to a variable,the value of that variable remains constant.
(or)
Once we declare a variable as final.the value of that variable cannot be changed.
2)It is useful when a variable value does not change during the life time of a program
static -
1)when we apply "static" keyword to a variable ,it means it belongs to class.
2)When we apply "static" keyword to a method,it means the method can be accessed without creating any instance of the class
Think of an object like a Speaker. If Speaker is a class, It will have different variables such as volume, treble, bass, color etc. You define all these fields while defining the Speaker class. For example, you declared the color field with a static modifier, that means you're telling the compiler that there is exactly one copy of this variable in existence, regardless of how many times the class has been instantiated.
Declaring
static final String color = "Black";
will make sure that whenever this class is instantiated, the value of color field will be "Black" unless it is not changed.
public class Speaker {
static String color = "Black";
}
public class Sample {
public static void main(String args[]) {
System.out.println(Speaker.color); //will provide output as "Black"
Speaker.color = "white";
System.out.println(Speaker.color); //will provide output as "White"
}}
Note : Now once you change the color of the speaker as final this code wont execute, because final keyword makes sure that the value of the field never changes.
public class Speaker {
static final String color = "Black";
}
public class Sample {
public static void main(String args[]) {
System.out.println(Speaker.color); //should provide output as "Black"
Speaker.color = "white"; //Error because the value of color is fixed.
System.out.println(Speaker.color); //Code won't execute.
}}
You may copy/paste this code directly into your emulator and try.
Easy Difference,
Final : means that the Value of the variable is Final and it will not change anywhere. If you say that final x = 5 it means x can not be changed its value is final for everyone.
Static : means that it has only one object. lets suppose you have x = 5, in memory there is x = 5 and its present inside a class. if you create an object or instance of the class which means there a specific box that represents that class and its variables and methods. and if you create an other object or instance of that class it means there are two boxes of that same class which has different x inside them in the memory. and if you call both x in different positions and change their value then their value will be different. box 1 has x which has x =5 and box 2 has x = 6. but if you make the x static it means it can not be created again.
you can create object of class but that object will not have different x in them.
if x is static then box 1 and box 2 both will have the same x which has the value of 5. Yes i can change the value of static any where as its not final. so if i say box 1 has x and i change its value to x =5 and after that i make another box which is box2 and i change the value of box2 x to x=6. then as X is static both boxes has the same x. and both boxes will give the value of box as 6 because box2 overwrites the value of 5 to 6.
Both final and static are totally different. Final which is final can not be changed. static which will remain as one but can be changed.
"This is an example. remember static variable are always called by their class name. because they are only one for all of the objects of that class. so
Class A has x =5, i can call and change it by A.x=6; "
Static and final have some big differences:
Static variables or classes will always be available from (pretty much) anywhere. Final is just a keyword that means a variable cannot be changed. So if had:
public class Test{
public final int first = 10;
public static int second = 20;
public Test(){
second = second + 1
first = first + 1;
}
}
The program would run until it tried to change the "first" integer, which would cause an error. Outside of this class, you would only have access to the "first" variable if you had instantiated the class. This is in contrast to "second", which is available all the time.
Static is something that any object in a class can call, that inherently belongs to an object type.
A variable can be final for an entire class, and that simply means it cannot be changed anymore. It can only be set once, and trying to set it again will result in an error being thrown. It is useful for a number of reasons, perhaps you want to declare a constant, that can't be changed.
Some example code:
class someClass
{
public static int count=0;
public final String mName;
someClass(String name)
{
mname=name;
count=count+1;
}
public static void main(String args[])
{
someClass obj1=new someClass("obj1");
System.out.println("count="+count+" name="+obj1.mName);
someClass obj2=new someClass("obj2");
System.out.println("count="+count+" name="+obj2.mName);
}
}
Wikipedia contains the complete list of java keywords.
I won't try to give a complete answer here. My recommendation would be to focus on understanding what each one of them does and then it should be cleare to see that their effects are completely different and why sometimes they are used together.
static is for members of a class (attributes and methods) and it has to be understood in contrast to instance (non static) members. I'd recommend reading "Understanding Instance and Class Members" in The Java Tutorials. I can also be used in static blocks but I would not worry about it for a start.
final has different meanings according if its applied to variables, methods, classes or some other cases. Here I like Wikipedia explanations better.
Static variable values can get changed although one copy of the variable traverse through the application, whereas Final Variable values can be initialized once and cannot be changed throughout the application.

Categories

Resources