public class NotActuallyImmutable {
private final int x;
public NotActuallyImmutable(int x) {
this.x = x;// line 1
}
public int getX() {
return x;
}
}
public class Mutable extends NotActuallyImmutable {
private int x = 123;
public Mutable(int x) {
super(x);
}
public int getX() {
return x++;
}
}
now in my main class
NotActuallyImmutable n = new Mutable(42); // line2
int x = n.getX();
System.out.println("x is"+x);
I am expecting the output as 42 but it return the output as 123. I am expecting 42 because at line 2 I am making object of class Mutable and then at line 1 I am setting value as 42. so when i do n.getX() I should get the this latest value not the default 123. I know Ii am missing something but not able to figure out the logic behind it?
The problem is that the field x in Mutable and the field x in class NotActuallyImmutable are not the same. The x that is returned by getX() is the one in Mutable (because the getX() that is invoked is Mutable.getX(), not NotActuallyImmutable.getX()).
Note that if you removed the instance field from Mutable, then you would have a compiler error because NotActuallyImmutable.x is private to NotActuallyImmutable and not accessible to any code in Mutable.
If you made NotActuallyImmutable.x a protected field, then Mutable.x would shadow it and you would still have the same behavior. If you removed Mutable.x in this case, you would still have a compiler error because you were trying to increment a final field.
If you remove Mutable.getX(), then the x that would be returned by getX() would be NotActuallyImmutable.x, despite there being another field of the same name in Mutable.
The private int x in Mutable and the private int x in NotActuallyImmutable are completely different fields that just have the same name.
This isn't a problem for the compiler because you can't access a private field from another class. So as far as the compiler is concerned, when you define Mutable, the x in NotActuallyImmutable is invisible and might as well not exist.
It is of course confusing for the programmer. If you rename one of the fields to y (and the getter method to getY) the behaviour seems much more intuitive.
NotActuallyImmutable n = new Mutable(42); // line2
This means you have an object of type NotActuallyImmutable but the instance of created object is Mutable.
so in this code your dealing with Mutable object which will return 123. as the number you passed is saved in NotActuallyImmutable not in Mutable,
n has two different x values which are visible in different contexts, the parent class's private member variable and the child class's private member variable.
NotActuallyImmutable n = new Mutable(42); // line2
Creates a new Mutable. Executes parent(x) which sets the parent class's x to 42.
int x = n.getX();
n is a Mutable instance so this calls Mutable's getX() which returns Mutable's value for x (123) rather than the parent's.
I agree with Nice explanations given in above answers. But to to just brief the final understanding. As i am doing new Mutable(42).getX(), jvm first will look in Mutable object to get the value of X not inside NotActuallyImmutable. If i remove getX() method from Mutable , i get the expected(as per my expectation) value i.e 42.
This example gets messy becoz variable name i.e X is same in parent and child class but good for understanding concept
Related
Non-static final variables can be assigned a value only once.
But why this assignment can happen only either within a declaration or in the constructor?
A final variable is defined to be immutable i.e., the value assigned to it will be the one and only for that variable x. As one can read from the JLS(§4.12.4.)
A variable can be declared final. A final variable may only be
assigned to once.
Now the constructor is just like any other method, except that it is the one that gets executed first when an object (non-static) is created from the class.
Hence, final variables can be assigned through constructors.
For example take the following code:
public class Test {
public final int x;
public Test(int x) {
this.x = x;
}
}
Compiler accepts this invocation because it is guaranteed that for that particular object its class's constructor gets invoked first and doesn't invoked again (i.e. constructor gets invoked one and only one time during the entire lifetime of object.)
However following code throws error: Non-static field 'x' cannot be referenced from a static context
public class Test {
public final int x;
static {
x = 5;
}
public Test(int x) {
this.x = x;
}
}
Since x is not a static field, it cannot be initiated within a static block.
This code would also throw error: Cannot assign a value to final variable 'x'
public class Test {
public final int x;
public Test(int x) {
this.x = x;
}
public void setX(int x) {
this.x = x;
}
}
That is because it is not guaranteed for this object, that the method setX would run first and only once. The programmer could call this method multiple times. Hence, the compiler throws an error.
So there is no way to make a variable "initializable" only once (e.g.,
a setter would block if variable was already assigned before) solely
with java syntax? I thought final might work this way but now I see
it's not.
For your question, you could simply make a variable private and add the condition to the setter method to add value only if variable is null.
For example:
public class Test {
private Integer x;
public Test() {
}
public Test(int x) {
this.x = x;
}
public void setX(int x) {
if (null == this.x) this.x = x;
}
public static void main(String[] args) {
Test y = new Test(5);
System.out.println(y.x);
y.setX(20);
System.out.println(y.x);
}
}
This is not thread safe by the way. I just added a simple example.
What does the keyword final mean in Java?
When used in a class declaration, it means that the class cannot be extended.
When used in a method, it means that the method cannot be overridden.
When used in a method parameter, it means the value of such parameter cannot be changed inside the method. (local constant)
When used in a class field ("variable), it means that it is a global constant.
Values for constants must be resolved at compile time. And, as the word implies, constants fields cannot change value. Therefore, the compiler does not allow the value to be set from a setter (mutator) method.
Contrary to what many believe, for a field to be constant, it does not have to be declared static and final. That said, since the value of a constant cannot be changed, each class instance will share the same value. Therefore, explicitly making them static reenforces this notion.
There is a fifth use of the keyword final and this is when used when local variables are declared. This is a more lengthy explanation.
What happens when you compile code?
I updated my answer because I think part of the problem is that some developers don't quite understand what happens when the code is compiled. As I mentioned before, constant values are resolved at COMPILE TIME. To understand this concept, consider the following example:
public class MyClass {
private final double PI = 3.14159;
// rest of class left out intentionally
}
If I compile this class on my laptop and then I deploy the code to some remote server, how does the server know that the global constant field PI has an assigned value of 3.14159? This is because when I compile this code, this value gets packaged with the byte code. The class constructor doesn't come into play at all in this case. HOWEVER, if the constant field is initialized to its DEFAULT value, then permanent (constant) value may be assigned via the constructor
public class MyClass {
private final double PI; // default value of 0.0
public MyClass(double value) {
PI = value;
}
// rest of code omitted intentionally
}
Here's where declaring a constant as static makes a difference. If a constant is also static, you can't do the above because calling a constructor implies that you can have multiple instances of MyClass and each instance could set a different value. This is clearly a violation of what a static member is. So, if you MUST declare a field as both static and final, understand that you cannot assign a value using this second approach. Only the first one I showed is allowed.
Final Stop's a Variable’s Reassignment
a short simple answer:
Use the keyword final when you want the compiler to prevent a variable from being re-assigned to a different object.
Whether the variable is a static variable, member variable, local variable, or argument/parameter variable, the effect is entirely the same.
Hope this helps friend =)
#StaySafe
When we assign objects of the same type to one another, the new object stores the address of the object that's being assigned to it. For instance, if I have my own class named CLA then the following code will produce 11 as the output:
public class CLA{
int val;
public static void main(String...args){
CLA ob1 = new CLA();
ob1.val = 10;
CLA ob2 = ob1;
ob1.val++;
System.out.printf("%d", ob2.val);
}
}
because ob2 would refer to ob1 and consequently show ob1's val.
However, the same doesn't happen for Wrapper classes. When I assign an Integer object to another, the operation simply behaves like we're dealing with values and not objects. As opposed to the above code, the output of the below code is 10:
Integer x = 10; //auto-boxed as new Integer(10)
Integer y = x;
x++;
System.out.printf("%d", y.intValue());
Why does this happen?
Do wrapper class objects get unboxed while being assigned to another object, so as to pass the value instead of the address??
When you do x++, it is the same as x = x + 1 so it is actually a new instance of Integer assigned to x but y still points to the old instance which value is 10.
Keep in mind that wrapper instances are immutable.
For an Integer x, the expression x++ can be understood like x = new Integer(x.intValue() + 1);. Its not exactly the same, but helps for understanding.
So, it doesn't modify the Integer object with the value 10 that x pointed to before the x++, it creates a new Integer object with the value 11 independent of the original 10 Integer, and assigns this 11 Integer to x.
But there's nothing in the x++ expression that would make y point to a different Integer instance. So y still points to the original 10.
That's the difference to the CLA example where you don't introduce a new instance with ob1.val++, but modify the single instance. If the Integer class had a public field value, then x.value++ would show the behaviour you expected - but the value field is (for good reason) private - not accessible to the outside.
This fails to compile (with an illegal forward reference error), as one would expect:
class test {
int x = x + 42;
}
But this works:
class test {
int x = this.x + 42;
}
What's going on? What gets assigned in the latter case?
It is too difficult to discover and forbid all accesses to x during x's initialization. For example
int x = that().x; | int x = getX();
|
Test that(){ return this; } | int getX(){ return x; }
The spec stops at "access by simple name" and does not try to be more comprehensive.
In another section, "Definite Assignment", the spec does the similar thing. For example
public class Test
{
static final int y;
static final int z = y; // fail, y is not definitely assigned
static{ y = 1; }
}
public class Test
{
static final int y;
static final int z = Test.y; // pass... because it's not a simple name
static{ y = 1; }
}
Interestingly, "Definite Assignment" specifically mentions that this.x is equivalent to x
(or, for a field, the simple name of the field qualified by this)
this clause could be added to the section quoted by NPE as well.
the usage is via a simple name (or a simple name qualified by this)
But in the end, it is impossible at compile time to analyze all possible usages/accesses to a field.
Summary: Both initializers access a field that's yet to be initialized (and therefore still has the default value of zero). Since this is likely to be a programming error, the language bans some simple forms of such access. However, it does not ban more complex form.
The behaviour is compliant with the JLS, specifically §8.3.2.3. Restrictions on the use of Fields during Initialization
The declaration of a member needs to appear textually before it is used only if the member is an instance (respectively static) field of a class or interface C and all of the following conditions hold:
The usage occurs in an instance (respectively static) variable initializer of C or in an instance (respectively static) initializer of C.
The usage is not on the left hand side of an assignment.
The usage is via a simple name.
C is the innermost class or interface enclosing the usage.
The first example satisfies all four conditions and is therefore invalid. The second example doesn't satisfy the third condition (this.x is not a simple name), and is therefore OK.
The overall sequence of events is as follows:
When an instance of a class is created, all fields are initialized to their type's default values.
Initializers are then run in textual order (from top to bottom).
Thus if an initializer refers to a field that appears later in the class definition (or to the field itself), it would see the default value of that other field. This is likely to be be a programming error and is therefore explicitly forbidden by §8.3.2.3.
If you circumvent §8.3.2.3 by, for example, using this. to forward-refer to a field, you'll see the default value (zero for int). Thus the following is well-defined and is guaranteed to set x to 42:
class test {
int x = this.x + 42;
}
In the first case compiler tries to evaluate expression 'x + 42' but fails because x is not initialized.
In the second case expression 'this.x + 42' is evaluated at runtime (because of 'this' keyword), when x is already initialized and has value 0.
Though I'm trying to understand why "this" is needed, I'm very confused about its purpose. For instance, I coded the following:
public static void main (String args[])
{
SandboxClass1 temp = new SandboxClass1(1,2,3);
System.out.println(temp.getX());
System.out.println(temp.getY());
System.out.println(temp.getZ());
System.out.println("----------------------------");
SandboxClass1 temp2 = new SandboxClass1(4,5,6);
System.out.println(temp2.getX());
System.out.println(temp2.getY());
System.out.println(temp2.getZ());
}
public class SandboxClass1
{
private int x = 1;
private int y = 1;
private int z = 0;
public SandboxClass1(int x, int y, int zz)
{
this.x = x;
this.y = y;
z = zz;
}
public int getX()
{
return(this.x);
}
public int getY()
{
return(this.y);
}
public int getZ()
{
return(this.z);
}
}
Why do I need to code "this.z = zz"
when I could just as well write, "z = zz"?
You don't, in this case. It's only required when you must eliminate ambiguity, like when parameters and instance variables share a name.
Some people prefer to use "this" to remove conceptual ambiguity and explicitly state that the code references an instance variable.
(On a side note, the parentheses around the return values are unnecessary and a bit noisy, IMO.)
In your SandboxClass1 constructor, you have two pairs of variables each called x and y. There's the x and y declared on the object itself ("private int x = 1"), and the separate x and y that are parameters to the constructor ("int x").
The local (parameter) variable shadows the class variable. So if in the constructor you just did
x = x;
the assignment would have no effect.
The keyword this is a reference to the object that the method/constructor was called on. In the statement
this.x = x;
you're using it to assign to the other x at class level. By qualifying the name, you can tell them apart.
It's not necessary to use this with the z/zz assignment because they have different names.
It's also not necessary in the getX/Y/Z methods because there are no local variables in those methods shadowing the relevant class variables. It does no harm though.
In the SandboxClass1 constructor two of the parameters (x and y) hide class variables because they are the same name. If you want to assign the class variable x to any value while in the code>SandboxClass1 constructor, you must address it using this.x to tell the compiler that "I want to assign the class scope variable named x, and not the method scope variable named x". The same applies to y.
Since the parameter z does not hide the class scope variable named zz you do not need to tell the compiler the scope of the zz variable, the class scope zz is the only recognized variable so that is the one that gets assigned.
It has the same effect. this is needed if there is a local variable which overrides a field of the class; then you get the local variable and not the class field.
An additional advantage you can indicate the variables better. If there is a this; it's a field; local variable otherwise.
the keyword this is used to refer to an attribute that is in the class. The keyword this was created to distinguish between class attributes and method parameters. like this:
public class human
{
public void setName(String name)
{
// the first name is a reference to the class attribute name
this.name = name;
// the second name is a reference to the method parameter name
}
// definition of the class attribute name
private String name;
}
when you use the keyword this it refers to the name variable inside the class heres an example where you don't need to use this:
public class Human
{
public void setName(String myName)
{
name = myName
}
private String name;
}
see now there is only 1 variable named name and there is only one variable named myName. In the other example there was 2 variables named name. One was a class attribute and one was a method parameter.
'this' operator just refines that property/field belongs to class you're working in. It's useful whe you have, for example, two variables with the same name:
this.zz = zz;
Unlike, say, Objective-C, "this" is optional when the method or variable is local, and there is no other conflicting use of the same name.
It comes in handy in conflicting-name cases, though, such as in methods that set instance variables such as void setOnionCount(int onionCount) where you would like to use "onionCount" for the formal parameter but still have "onionCount" as the instance variable name. In such a case you can do this.onionCount = onionCount; and everyone is happy (except, I suppose, those in the Peanut Gallery who'll object to this technique).
"this" is also absolutely necessary in cases where you need to pass a reference to the current object to some other class, of course.
hey this is use to provide reference of invoking object. That i.e say suppose ur class is box then if you want to provide it's object then you can provide it within the class box using this keyword.
class Box {
int x;
public Box(int x){
this.x = x;
}
}
here in this case if your object is ob (i.e Box ob = new Box(1)) then the reference it will be passed to the itself.
Note: you cannot use this keyword outside of the class. If you use so then it will give reference of another class.
for complete detail on this keyword refer following link
http://download.oracle.com/javase/tutorial/java/javaOO/thiskey.html
I am reading the book Effective Java.
In an item Minimize Mutability , Joshua Bloch talks about making a class immutable.
Don’t provide any methods that modify the object’s state -- this is fine.
Ensure that the class can’t be extended. - Do we really need to do this?
Make all fields final - Do we really need to do this?
For example let's assume I have an immutable class,
class A{
private int a;
public A(int a){
this.a =a ;
}
public int getA(){
return a;
}
}
How can a class which extends from A , compromise A's immutability ?
Like this:
public class B extends A {
private int b;
public B() {
super(0);
}
#Override
public int getA() {
return b++;
}
}
Technically, you're not modifying the fields inherited from A, but in an immutable object, repeated invocations of the same getter are of course expected to produce the same number, which is not the case here.
Of course, if you stick to rule #1, you're not allowed to create this override. However, you cannot be certain that other people will obey that rule. If one of your methods takes an A as a parameter and calls getA() on it, someone else may create the class B as above and pass an instance of it to your method; then, your method will, without knowing it, modify the object.
The Liskov substitution principle says that sub-classes can be used anywhere that a super class is. From the point of view of clients, the child IS-A parent.
So if you override a method in a child and make it mutable you're violating the contract with any client of the parent that expects it to be immutable.
If you declare a field final, there's more to it than make it a compile-time error to try to modify the field or leave it uninitialized.
In multithreaded code, if you share instances of your class A with data races (that is, without any kind of synchronization, i.e. by storing it in a globally available location such as a static field), it is possible that some threads will see the value of getA() change!
Final fields are guaranteed (by the JVM specs) to have its values visible to all threads after the constructor finishes, even without synchronization.
Consider these two classes:
final class A {
private final int x;
A(int x) { this.x = x; }
public getX() { return x; }
}
final class B {
private int x;
B(int x) { this.x = x; }
public getX() { return x; }
}
Both A and B are immutable, in the sense that you cannot modify the value of the field x after initialization (let's forget about reflection). The only difference is that the field x is marked final in A. You will soon realize the huge implications of this tiny difference.
Now consider the following code:
class Main {
static A a = null;
static B b = null;
public static void main(String[] args) {
new Thread(new Runnable() { void run() { try {
while (a == null) Thread.sleep(50);
System.out.println(a.getX()); } catch (Throwable t) {}
}}).start()
new Thread(new Runnable() { void run() { try {
while (b == null) Thread.sleep(50);
System.out.println(b.getX()); } catch (Throwable t) {}
}}).start()
a = new A(1); b = new B(1);
}
}
Suppose both threads happen to see that the fields they are watching are not null after the main thread has set them (note that, although this supposition might look trivial, it is not guaranteed by the JVM!).
In this case, we can be sure that the thread that watches a will print the value 1, because its x field is final -- so, after the constructor has finished, it is guaranteed that all threads that see the object will see the correct values for x.
However, we cannot be sure about what the other thread will do. The specs can only guarantee that it will print either 0 or 1. Since the field is not final, and we did not use any kind of synchronization (synchronized or volatile), the thread might see the field uninitialized and print 0! The other possibility is that it actually sees the field initialized, and prints 1. It cannot print any other value.
Also, what might happen is that, if you keep reading and printing the value of getX() of b, it could start printing 1 after a while of printing 0! In this case, it is clear why immutable objects must have its fields final: from the point of view of the second thread, b has changed, even if it is supposed to be immutable by not providing setters!
If you want to guarantee that the second thread will see the correct value for x without making the field final, you could declare the field that holds the instance of B volatile:
class Main {
// ...
volatile static B b;
// ...
}
The other possibility is to synchronize when setting and when reading the field, either by modifying the class B:
final class B {
private int x;
private synchronized setX(int x) { this.x = x; }
public synchronized getX() { return x; }
B(int x) { setX(x); }
}
or by modifying the code of Main, adding synchronization to when the field b is read and when it is written -- note that both operations must synchronize on the same object!
As you can see, the most elegant, reliable and performant solution is to make the field x final.
As a final note, it is not absolutely necessary for immutable, thread-safe classes to have all their fields final. However, these classes (thread-safe, immutable, containing non-final fields) must be designed with extreme care, and should be left for experts.
An example of this is the class java.lang.String. It has a private int hash; field, which is not final, and is used as a cache for the hashCode():
private int hash;
public int hashCode() {
int h = hash;
int len = count;
if (h == 0 && len > 0) {
int off = offset;
char val[] = value;
for (int i = 0; i < len; i++)
h = 31*h + val[off++];
hash = h;
}
return h;
}
As you can see, the hashCode() method first reads the (non-final) field hash. If it is uninitialized (ie, if it is 0), it will recalculate its value, and set it. For the thread that has calculated the hash code and written to the field, it will keep that value forever.
However, other threads might still see 0 for the field, even after a thread has set it to something else. In this case, these other threads will recalculate the hash, and obtain exactly the same value, then set it.
Here, what justifies the immutability and thread-safety of the class is that every thread will obtain exactly the same value for hashCode(), even if it is cached in a non-final field, because it will get recalculated and the exact same value will be obtained.
All this reasoning is very subtle, and this is why it is recommended that all fields are marked final on immutable, thread-safe classes.
If the class is extended then the derived class may not be immutable.
If your class is immutable, then all fields will not be modified after creation. The final keyword will enforce this and make it obvious to future maintainers.
Adding this answer to point to the exact section of the JVM spec that mentions why member variables need to be final in order to be thread-safe in an immutable class. Here's the example used in the spec, which I think is very clear:
class FinalFieldExample {
final int x;
int y;
static FinalFieldExample f;
public FinalFieldExample() {
x = 3;
y = 4;
}
static void writer() {
f = new FinalFieldExample();
}
static void reader() {
if (f != null) {
int i = f.x; // guaranteed to see 3
int j = f.y; // could see 0
}
}
}
Again, from the spec:
The class FinalFieldExample has a final int field x and a non-final int field y. One thread might execute the method writer and another might execute the method reader.
Because the writer method writes f after the object's constructor finishes, the reader method will be guaranteed to see the properly initialized value for f.x: it will read the value 3. However, f.y is not final; the reader method is therefore not guaranteed to see the value 4 for it.