Can I use the term "Constant Object" in the place of the term "Immutable Object"? Though I get the feeling that Immutable for an Object is what Constant is for a variable, I am not sure if this terminology is accepted. Please help me understand.
In fact, in Java the term constant has no defined meaning. It occurs in the JLS only in the larger term compile time constant expression, which is an expression which can (and must) be calculated by the compiler instead of at runtime. (And the keyword const is reserved to allow compilers to give better error messages.)
In Java, we instead use the term final to refer to variables (whether class, object or local ones) who can't be changed, and immutable when we refer to objects who can't change. Both can be used when speaking about a variable x - the first then means the variable itself (meaning it can't be switched to another object), the second means the object behind the variable. Thus here the two meanings are orthogonal, and are often combined to create a "true constant".
I would read constant as being the same object (the same reference), whereas immutable clearly means to me the fact that the object doesn't change.
Since these are two different things, I would perhaps refer to this:
private final Immutable i = new Immutable();
as being a constant immutable object.
Constant often has a very specific meaning in different programming languages. In java, a constant already refers to a constant variable, a variable that cannot be changed after assignment, e.g.:
final int FOO = 1;
FOO = 4; // constant variable cannot be changed.
An immutable object is a constant object in the sense that its properties can never be changed, but of course an object pointed to by a constant variable can still be changed. So to avoid confusion, the term immutable (which literally means "unchanging over time") is used.
They are very close in meaning, with the understanding that an Object contains methods while a Constant is generally considered to only contain data.
Within Java, there's the additional consideration of the keyword final, which basically means non-reassignable. Some people will casually call a final variable a constant (as it's reference to a particular object is a constant. This often comes about due to confusion as to the particular roles of the member and the object it refers to, as 95% of the time a person does this to refer to an immutable Object.
Not every method is to return back data that depends wholly upon the internal members. For example System.currentTimeMillis() returns back a Unix like timestamp, yet there would be no need for the actual "System" object to change.
Immutability of the object means it can't transform it's state... i.e. can't mutate... For examle
final class Person {
private int age = 0;
public Person(int age) { this.age = age; }
}
The object to this type are immutable objects since you can't change it's state.... (forget Reflection for a moment)
Constant at the other hand in Programming means inline... Even the compiler does that they inline the values of the constant variables for primative types... for object types it means the ref variable can't be reassigned.
Related
as I see it C++ constant pointer, C++ reference and Java final keyword (final on a variable) are all the same thing or at least act the same way.
they prevent the variable to change his "pointed address" but the internal value can be changed.
am I right for thinking that?
If not what are the differences?
regarding the c++ part
what are the differences between a constant pointer and a reference?
they look like a different way to do the same thing, why adding the reference concept to c++ if the concept already existed in the form of constant pointer?
regarding the Java part
is there a way(in Java) to simulate the same behavior of a pointer to a constant value of c++? basically is there a way to make constant values?
something more similar to const Shape* s = new Shape;
edit: I found at least 1 reason to introduce the reference concept
when we define a copy constructor we need to get the object as an argument and without a reference, we will get an infinite loop
C++:
class Shape{
public:
int member = 3;
};
Shape s1;
Shape s2;
Shape* const cp_var_1 = &s1;
cp_var_1->member = 5; // valid
cp_var_1 = &s2; //not valid
Shape& ref_var_2 = s1;
ref_var_2.member = 6; // valid - s1 changed as well
// cant change ref_var_2 to reference other variable (like s2)
ref_var_2 = s2;
// assignment operator called - s1 and s2 content are the same
// but ref_var_2 still reference s1
Java:
class Shape{
public int member = 3;
}
Shape s1 = new Shape();
Shape s2 = new Shape();
final Shape final_var_3 = s1;
final_var_3.member = 7; // valid
final_var_3 = s2; // not valid
Yes, you're precisely correct: in final var_3 = s1;, the final prevents you from ever making var_3 reference anything else, but you can dereference the variable and do whatever you want to what you find there: var_3.member = 7; is therefore valid (the dot is the dereference operator).
Note that the final keyword in java is used for different purposes. You can mark classes as final, which means they cannot be extended. (class Foo extends SomeClassMarkedFinal {} will not compile). final can also be applied to methods: In that case, it means any subclass may not override this method. Whilst the english name final does seem like a good term for all of this behaviour, the final as used on variable declarations, and the final as used on methods and classes, are otherwise utterly unrelated.
Many java types (such as java.lang.String, java.lang.Integer, and many more) are so-called 'immutable': These objects have absolutely no way to change anything about them. java's strings are objects (not ersatz char arrays), you can't access the underlying char array, there is no clear() or setChar() method, etc: Therefore, a final variable of type string is completely constant.
Java does not (currently) offer any way of marking a type as 'constant' in this sense, and it probably wouldn't make much sense to add this as a notion. For example, in java, java.io.File, which represents a file path, is immutable: It has absolutely no methods to mutate any of its state.
And yet, is it immutable? Is it 'constant'? If I run file.delete(), I can most assuredly observe a change, even though the object itself (which has just one field, of type string, containing a file path) hasn't changed at all.
The final keyword in java does have (basically) the same effect as a reference or constant pointer in c++, but const in c++ ends up being a lot more general and more powerful.
If you have a pointer or a reference to a const object, then the object itself should be regarded as immutable. For example, if a function takes a const reference to an object, I can safely pass in objects with the assumption that they won’t be modified. And if I write a const member function, then I’m promising that that member function won’t modify the underlying object.
Adding const to function parameters (especially those passed by reference or pointer) can make it a lot easier for programmers to reason about code. They know that they can expect those inputs to remain unchanged. This is an enormous benefit when tracking down bugs, and it makes it easier to reason about the interface for external libraries that use const properly.
Finally, unlike in Java, a function that takes a value by reference in C++ is allowed (and encouraged) to assume that the reference you passed it isn’t null. This is good. If you write your code so that your references are never null, the code will be simpler, cleaner, and faster (since you won’t have to do null checks) .
Strategy for defining immutable class says that
all the fields should be final.
For ex:
private String name;
Why does it have to be final?
Since I am not giving setter methods for it? It can't be changed.
Thanks.
If you read
private final String name;
you know the field is immutable.
If you read
private String name;
you have to read the entire class to check it is not changed anywhere. This is means much more work for you.
You may remember now, having just written the class that you didn't add a setter, but after writing many more classes you read your own class six month later, you won't remember reliably.
Even if it is not changed now, someone (possibly yourself) could change it later by adding code. However, you might have made the assumption the value won't change.
In short, only make it non-final when you mean the value to change, and make it final when you didn't expect it to change. Don't leave it as a may be/may be not.
Now imagine you are used to being clear about which fields can be changed and which cannot. This saves you a lot of work when reading some else's code. But you discover that you are reading code which is not clear and non-final doesn't mean it was changed, it now means you have to check things, you wouldn't normally have to check which is one more headache in trying to understand some code you really don't need.
A simple example of how much harder it is to read code to determine if a field is effectively final.
public class A {
static class B {
private int x;
}
// some code
This all looks fine up to this point, no setters or even methods in B. So B.x is immutable right?
static class C {
public void update(B b, int x) {
b.x = x; // this really compiles
}
}
}
Oops no, you have to read the whole class file.
It is far better for you to make every field you can final (which should have been the default IMHO) when you write the code, rather than leaving it for someone to figure out later.
The main reason (IMHO) is that when field is final is guaranteed to be visible in other threads immediately after constructor is finished.
Keeping the field final emphasizes the fact that it cannot be changed anywhere else.
Self documenting code the the field should not be changed
Compiler will help you by giving error if you change the field somewhere else
So final helps in many ways for making object Immutable.
It's good practice to make immutable fields final, even on otherwise mutable objects.
Note that private fields of one object in fact CAN be accessed by other instances of the same class.
An object (class or instance) is immutable, if its internal state cannot be changed (reflection doesn't count).
Making a field final guarantees only that the value (if it's a primitive) or reference (for non-primitives) cannot be changed.
For non-primitives, this doesn't automatically mean that the referenced value is also immutable. Which means that if your final field references, for example, a list, one cannot exchange the list, but add/remove values from it, thus changing the state of the object.
For an object to be immutable:
The internal state must be determined upon construction and can never change
This means all fields that define the state must be final (you may have other helper fields which don't belong to the state, that's ok but rare).
This also means that all refernced objects must be immutable. Some objects such as String are already immutable, others such as collections can be wrapped to make them immutable (Collections.immutableList|Set|Collection|...)
Making primitive types final ensures immutability. However making non primitive objects final sometimes makes no sense since final object states can be mutated.As Greg points out this depends on the type of Object in question
As the example you showed, all properties are primitive hence final keword make sense.
One benifit of declaring a field final is that it allows compiler to detect attempts to change the field during refactoring. A class can be immutable even if its fields are not final.
JVM guarantees that final fields of a class will be initialized before any thread gets hold of the object. Without this guarantee, a reference to an object may be published, i.e. become visible, to another thread before all the fields of this object are initialized, due to reorderings or other optimizations. This could cause racy access to these fields.
This is why, when creating an immutable object, you should always make all its fields final, even if they are not accessible via getter methods.
final Object o;
List l = new ArrayList(){{
// closure over o, in lexical scope
this.add(o);
}};
why must o be declared final? why don't other JVM languages with mutable vars have this requirement?
This is not JVM-deep, it all happens at syntactic-sugar level. The reason is that exporting a non-final var via a closure makes it vulnerable to datarace issues and, since Java was designed to be a "blue-collar" language, such a surprising change in the behavior of an otherwise tame and safe local var was deemed way too "advanced".
It's not hard to deduce logically why it has to be final.
In Java, when a local variable is captured into an anonymous class, it is copied by value. The reason for this is that the object may live longer than the current function call (e.g. it may be returned, etc.), but local variables only live as long as the current function call. So it is not possible to simply "reference" the variable because it may not exist by then. Some languages like Python, Ruby, JavaScript, do allow you to reference variables after the scope is gone, by keeping a reference to the environment in the heap or something. But this is hard to do with the JVM because local variables are allocated on the function's stack frame, which is destroyed when the function call is done.
Now, since it is copied, there are two copies of the variable (and more, if there are more closures capturing this variable). If they were assignable, then you can change one of them without changing the other. For example, hypothetically:
Object o;
Object x = new Object(){
public String toString() {
return o.toString();
}
};
o = somethingElse;
System.out.println(x.toString()); // prints the original object, not the re-assigned one
// even though "o" now refers to the re-assigned one
Since there is only one o variable in the scope, you would expect them to to refer to the same thing. In the example above, after you assign to o, you would expect a later access of o from the object to refer to the new value; but it doesn't. This would be surprising and unexpected to the programmer, and violates the principle that uses of the same variable refer to the same thing.
So to avoid this surprise, they mandate that you cannot assign to it anywhere; i.e. it has to be final.
Now, of course, you can still initialize the final variable from a non-final variable. And inside the closure, you can still assign the final variable to something else non-final.
Object a; // non-final
final Object o = a;
Object x = new Object(){
Object m = o; // non-final
public String toString() {
return ,.toString();
}
};
But then this is all good since you are explicitly using different variables, so there is no surprise about what it does.
In Java when a final field is assigned a constant value compile-time, it usually makes sense declaring it static. It saves overhead according to the relevant PMD rule.
Does it make any sense or difference doing it in GWT regarding the generated Javascript code?
If the variable is assigned when it is declared final, then yes, static makes a certain amount of sense, but there are cases where it should not be static:
public MyClassWithFinal {
private final String finalVar;
public MyClassWithFinal(String name) {
this.finalVar = name;
}
}
Another case: If the instance var is not a string or number constant, but requires running a constructor, that constructor may have side effects each time it is invoked, so running it only once is different than running it multiple times.
That said, GWT will inline/intern constant string values, so if you have multiple String fields all assigned to the same value, GWT will probably detect that and promote them all to static.
public final String constant = "Some Constant that really ought to be static";
GWT will notice that this is never assigned except when declared, and may even remove the field itself.
The best rule is to start with the best (i.e. most readable, most maintainable, most efficient) Java code, and to only break from that in cases where GWT requires something specific. This is not one of those cases: the compiler should perform the same basic optimizations no matter how you write this.
A field marked as final doesn't mean that it is immutable, only that its reference won't point to any other memory chunk. Therefore, it can only make sense to make a field static if it is really immutable, or if it is a primitive.
For instance, it's common to declare lists as final if you want to make sure that they will never point to a different list object, but the list itself can still be filled with data, cleared, filled again, etc. And of course, each object declaring such list does not mandatory want to share it among every instances.
private final List<...> list = new ArrayList<...>();
Final keyword is there to prevent you from doing mistakes, like setting to null a reference that should never change.
I know that Strings are immutable.
Then, what is the difference between:
String name ="Name";
final String name ="Name";
Why do we use final in this context? Because String is already immutable there seems to be no need. Second related question, why are String's immutable?. Other Data Types like int, boolean are not. If String is immutable does that make it thread-safe? I read that "if String been mutable, a request to load "java.io.Writer" could have been changed to load "mil.vogoon.DiskErasingWriter"" means ?
There are a lot of questions here, but here are a few notes that should answer most of them:
final means the variable can be assigned only once. It has nothing to do with mutability, which is a property of the object, rather than the variable (which is simply a handle)
String is immutable, because you can't change its internal state (it has a private char[] chars that hold the characters). Primitives are also immutable. This is better visible in their wrapper equivalents - Integer, Long etc.
yes, a String is thread-safe, because its state cannot be changed no matter how many threads work with it. Every operation on the string results in a new instance, rather than changing the existing one.
final means you cannot assign the variable a new value.
String name = "Name";
name = "MyName"; // legal
final String name = "Name";
name = "MyName"; // illegal, compiler error
Here is an article on why strings are immutable:
http://javarevisited.blogspot.com/2010/10/why-string-is-immutable-in-java.html
I read that "if String been mutable, a request to load "java.io.Writer" could have been changed to load "mil.vogoon.DiskErasingWriter""
OK. First thing to realize is that this is a hypothetical discussion. String is not mutable.
So now imagine this piece of code:
public static final String CLASS_NAME = "java.io.Writer";
...
Class<?> clazz = Class.forName(CLASS);
What class does this actually load?
If String's were mutable, some nefarious code running in the security sandbox would be able to mutate the contents of the String object that CLASS_NAME refers to. In particular, it could change it from "java.io.Writer" to "mil.vogoon.DiskErasingWriter". The net result is that your application would be tricked into loading the wrong class.
By making String an immutable type (and one or two other things) this attack mechanism is foiled.
Like William said :
final means you cannot assign the variable a new value.
In addition, if you play with anonymous inner class like that :
final String mystring = "Hello";
button.addClickHandler(new ClickHandler() {
void click() {
System.out.println(mystring);
}
});
The mystring object must be final.
Its the difference between an object and its reference. A final variable can only be assigned a value once. This is true regardless of wether that variable refers to an immutable object or not.
Note that an 'immutable' object is itself typically (but not necessarily) composed of sets of final references.
The other points have already been answered here, but you are still looking for an explaination to that quote you found:
if String been mutable, a request to load "java.io.Writer" could have
been changed to load "mil.vogoon.DiskErasingWriter"
For reference, this appears to be from a different SO answer which is somewhat short and leaves out detail.
In general, if you write a public class that accepts mutable objects and stores them, or that returns a mutable object it is storing, the calling code can change that object from under the feet of that class.
For an example. Disclaimer: I don't know much about ClassLoader, so this is just for the sake of illustrating the problem. ClassLoader has a function loadClass(String name). Imagine that method first checks if the class of that name is valid or trusted, and then loads it. Now if String was mutable, the calling code could change the class name from under the class loader's feet after it had already checked the class, and thus circumvent security measures.
Of course, if String was mutable, one could hope the implementation of ClassLoader would first make a defensive copy of the String. That way, the calling code has no chance of circumventing the security since it has no way to modify the contents of the copy. This is a general rule: Don't let calling code have any handle on mutable internal data of your class.
So String does not need to be immutable to ensure safe class loading. However, with immutable objects it is easier to ensure this kind of security, since they simply can't be changed from under you.