Why can I still make changes to this final variable? [duplicate] - java

This question already has answers here:
Final variable manipulation in Java
(11 answers)
Closed 8 years ago.
If name is declared final, why i can still call name.append and the output is: shreya? I thought final variables cannot be changed once a value is assigned?
public class Test1 {
final static StringBuilder name = new StringBuilder("sh");
public static void main(String[] args) {
name.append("reya");
System.out.println(name);
}
}

final refers to not being able to change the reference, e.g. you cannot say name = new StringBuilder(). It does not make the referenced object immutable.
Immutability is a property of a class. An object of a mutable type is always mutable.

You have to start making the distinction between variables, values (reference values and primitive values) and objects and primitives.
A variable is container for a value. That value is either a reference value (for objects) or a primitive value.
You cannot use the assignment operator to assign a new value to a final variable once it has been initialized with its original value.

Related

Java 8 stream variable used in lambda should be final or effectively final [duplicate]

This question already has answers here:
Variable used in lambda expression should be final or effectively final
(9 answers)
Closed 4 years ago.
This question is already asked. But today I found something odd. For the following code:-
public static List<EsbBucketInstanceDefinition> convertBucketDefinitionList(List<BucketInstanceDefinitionV1> bucketInstanceDefinitionV1List) {
List<EsbBucketInstanceDefinition> response = new ArrayList<>();
List<EsbBucketInstanceDefinition> finalResponse = new ArrayList<>();
bucketInstanceDefinitionV1List.stream().forEach(e -> {
EsbBucketInstanceDefinition esbBucketInstanceDefinition = new EsbBucketInstanceDefinition();
esbBucketInstanceDefinition.setInstanceType(e.getInstanceType());
esbBucketInstanceDefinition.setReportingGroup(e.getReportingGroup());
esbBucketInstanceDefinition.setSliceVolume(e.getSliceVolume());
esbBucketInstanceDefinition.setCounterName(e.getCounterName());
esbBucketInstanceDefinition.setSubscriberGroupId(e.getSubscriberGroupId());
// response.add(esbBucketInstanceDefinition); compiler error variable used in lambda should be final or effective final
finalResponse.add(esbBucketInstanceDefinition);
});
return finalResponse;
}
For this works fine. Looks like only variable name finalResponse is working. How and why? Is it valid to do?
References may only be made to (effectively) final variables from within a lambda.
The reference held by finalResponse in effectively final, because it never changes. Note that changing the reference means assigning a new value to it, eg
finalResponse = someOtherList;
Changing the state of the object referred to (eg adding items to the list referred to by finalResponse) is irrelevant to what the value held by the variable finalResponse, ie
finalResponse.add(something);
Does not change the variable finalResponse; it only changes the object to which finalResponse refers.

Java: Modifying Objects by Method Call [duplicate]

This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 4 years ago.
I've read a gazillion times that in Java, arguments passed to methods cannot be modified by the methods. Nonetheless, I find I can modify objects I create as opposed to Java Objects. Consider the following code:
// My Integer Object
class MyInteger {
Integer val;
}
// Change Java Object
public void test1() {
Integer intval; // Integer object
intval = 123;
setInteger( intval ); // THIS DOESN'T WORK
TTY.putR( "Integer Object="+intval);
}
// Change My Object
public void test2() {
MyInteger myInt; // MyInteger object
myInt = new MyInteger();
myInt.val = 456;
setMyInteger( myInt ); // THIS WORKS!
TTY.putR( "MyIntegerObject=" + myInt.val );
}
// Set an Integer object
public void setInteger( Integer val) {
val = 888;
}
// Set a MyInteger object
public void setMyInteger( MyInteger myint) {
myint.val = 999;
}
test1 doesn't work as I have been warned. But test2 works just fine. AFAIK, both are objects and are passed by reference. So how come one works and the other doesn't? (Note: TTY is my print function)
You have either read things that were wrong, or misunderstood what you've been told.
If you pass 'a' to a java method, you cannot have the method change 'a' to be something other than 'a'. However, you can modify 'a'.
In other words, you cannot create an object of the same class as 'a' and return that in place of 'a'. The only way you can return an object created by the method is either to have a place to put a reference to that new object within an object passed to the method, or to return it as the return value from the method.
The best way I've seen this explained:
You pass an object A pointing to a memory address P.
A ===> P
When you modify A by doing A.foo = bar, A is still pointing to P, so the object at P has its property foo changed. However, let's say you want to completely reassign A, and so do A = new MyCoolObject(). This means
P_New <=== A ==/=> P
So when you modify A by doing A.foo = bar, A is no longer pointing to P, so the object at P_New has its property foo changed, but the object at P remains unchanged. This means when you exit the method and go back to whatever parent called the method, A will be completely unchanged.
Disclaimer: I saw this on another Stack Overflow article probably 5 years ago, and am too lazy to find it. If you're reading this right now and you're the person who wrote this, thanks, and forgive my casual plagiarism.
I think you are confused by pass-by-reference vs. pass-by-value. Read this to help clear it up.
You might also have misinterpreted what you've read. A mutable Object can be mutated anywhere -- where it is created or by a method it is passed to.
Good luck.
Because MyInteger the val is a public variable. So ANYONE can modify it.
// Change MyInteger object
public void setMyInteger( MyInteger val) {
val.val = 999; // ACCESING TO A PUBLIC VAR and SETTING IT
}
// Change an Integer object
public void setInteger( Integer val) {
val = 888; // Accesing to the value of the Variable and not modifing it
}
Java is a pass by value language. When you invoke any method with argument it creates new variable and you are changing this variable.
You can look at this also,
Is Java "pass-by-reference" or "pass-by-value"?

Java pass by value query [duplicate]

This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 6 years ago.
Since java is pass by value.In below code we are passing a value to appendStringMethod not a reference, then why in main method we get HelloWorld not just Hello after calling appendStringMethod() in main.
public class test {
public static void main(String args[]) {
StringBuilder str = new StringBuilder("Hello");
appendStringMethod(str);
System.out.println(str);
}
static void appendStringMethod(StringBuilder s) {
s.append("World");
}
}
However in below code, values are not swapped.
public class Mock {
public static void main(String args[]) {
StringBuilder str1 = new StringBuilder("Hello");
StringBuilder str2 = new StringBuilder("World");
swap(str1, str2);
System.out.println(str1);
System.out.println(str2);
}
static void swap(StringBuilder s1, StringBuilder s2) {
StringBuilder s= s1;
s1=s2;
s2=s1;
}
}
It's because the reference to the StringBuilder is passed by value. You can add characters and they will be in the instance after the method returns. This in the end acts like a pass by reference. It works similarly with the Collection classes (List, Map,...), as well as your own classes.
In the case of primitive types (int,...), Java behaviour is simple: The value is copied in another instance of the primitive type.
In case of Objects, this is the same: Object variables are pointers that holds the Object’s address so the references are copied. The only exception I can think of are String Objects as the characters are stored in an array declared final so that it cannot be modified.
While Java is technically pass by value for everything, as spoken about here, It's best not to think of it like that.
When passing an instance of a class into a method, you're really passing the reference of the object by value.
StringBuilder str = new StringBuilder("Hello");
appendStringMethod(str);
In this code, you are passing a reference to the StringBuilder instance into the appendStringMethod by value.
As a result, str will become "HelloWorld" once the method has been called.
Note: This doesn't apply to primitives such as int and char. Since they are not actual objects, they won't have a reference. This means they will be passed by value in the "expected" way.
In java we pass by value of reference. Have a look at a following example:
public void foo(Integer i) {
i = new Integer(1000);
}
public void bar(Integer i) {
i++;
}
Integer n = new Integer(2000);
foo(n);
bar(n);
System.out.println(n.toString());
I believe that much of the confusion on this issue has to do with the
fact that different people have different definitions of the term
"reference". People coming from a C++ background assume that
"reference" must mean what it meant in C++, people from a C background
assume "reference" must be the same as "pointer" in their language,
and so on. Whether it's correct to say that Java passes by reference
really depends on what's meant by "reference".
--first comment

In Java, Variable got initialize without constructor, How it come possible? [duplicate]

This question already has answers here:
Default values and initialization in Java
(11 answers)
Closed 6 years ago.
I understand that, Constructors are used to initialize the instance variables.
Default constructor will create by compiler itself, if we did not create the same.
If we are creating the parameterized constructor then compiler won't create the default constructor.
I have written a code, to ignore the instance variable to be handled by constructor. But it got initialize without constructor. How it come possible to initialize variable without the constructor?
Please find the code snippet below for better understanding
public class ClassWithoutDefault {
int number;
String name;
//Intailizing name variable alone by using parameterized constructor
ClassWithoutDefault(String name){
this.name = name
}
void show(){
System.out.println("Name is"+name+"Number is"+number );
}
}
//Main class
public class ConstructorTest {
public static void main(String[] args) {
ClassWithoutDefault classWithoutDefault = new ClassWithoutDefault("Hari");
classWithoutDefault.show();
}
}
Output
Name is Hari
Number is 0
How the variable number got initialized as 0, without the constructor?. Could any one please help me to understand this?
Each member variable is assigned a default value (when an instance of a class is created), and if you don't assign it anything else, it retains that default value. The default value of primitive numeric types is 0.
Whenever a new object of a class is created, :
Strings are initialized by null.
Numbers are initialized by 0 (integers), or 0.0(floating-point).
booleans are initialized by false.
chars are initialized by \u0000
Arrays are initialized by the default values of their components.
Other Objects are initialized by null.
Hence, your number was initialized by 0.
When you create an object,first compiler copy that class file to memory and create the template of the object in the memory. And then it creates a copy according to that template and add it to your reference variable.
If you declared a static variable then that variable is created with the template,thats why static variables have the last updated value everytime. Because for all objects there is only one common variable in that name in the memory.
But when you create instance variable it is made with every object.
So when an object is created everytime, it is initialized to its Default Value.
//byte 0
//short 0
//int 0
//long 0
//float 0.0
//double 0.0
//char null
//boolean false
//Reference Type, class type - null

String class in java [duplicate]

This question already has answers here:
Immutability of Strings in Java
(26 answers)
How do I compare strings in Java?
(23 answers)
Closed 8 years ago.
In java String is a class and it is imutable so we can not change its value.In following code it will concate other string without any error.So I want to ask that if it is immutable then why in this following code value of String is changed??
import java.util.*;
public class conc
{
public static void main(String args[])
{
String a="Sheetal";
a=a+"Ga";
System.out.println("Result:"+a);
}
}
In the code that you have shown, you have not changed the original String object.
Instead, you have created a new String object, which represents a + "Ga", and then re-assigned it to the reference variable a.
Note that all variables in Java other than primitive types are references.
You are creating a new object by concatenating two strings, that is: You are not changing the object referenced by a but assigning to that reference the value referencing to a new String object.
String a="Sheetal";
a=a+"Ga"; // now this is not the same object you are referring early
When you alter your a will create a new String.
Your original String is not change that's why we call String are immutable and new String will create in the heap.
In this moment there are 2 object in your heap. now a is referring new Object.

Categories