#are ints mutable
1 messages · Page 1 of 1 (latest)
<@&987246399047479336> please have a look, thanks.
A variable or fields holds a value. That value is either a primitive value or a reference.
If the field or variable is not 'final', it can be assigned a new value.
Assigning replaces the value.
eg...
int i = 10; // copy the literal int value 10 into i
i = 20; // copy the literal int value 20 into i
note that this is how the observable semantics work. Java is free to take shortcuts as long as they're not observable.
thanks. but how do you know i doesn't hold a reference?
is it observable?
and I was told ints are mutable, because you can do like i++. but how do you know that's not just assigning a new int to i?
You can think of 'replace' above as 'overwrite'.
String s = "Foo"; // copy the String literal reference to "Foo" into s
s = "Bar"; // copy the String literal reference to "Bar" into s
The old reference value is overwritten/replaced. The immutability of String has nothing to do with the finality of the reference variable.
int is a primitive type, the most likely implementation is that it is not a reference (though the Java runtime can do what it likes).
all variables are either primitives or references to object types. There are no references to primitives in Java.
but refraining from looking under the hood, do primitive types have any observable non-referency behaviour that separates them from references?
i want to know why it's meaningful to say that in Python every type has reference semantics, but in Java primitive types have value semantics
in my mental model of Java i is a reference to an int and the semantics are exactly like if i had type Integer
Python exposes its internal representation as a dictionary of values. It's possible to refer to these.
In Java, for a variable i, the i doesn't exist in the bytecode... it's just a source-code label for human convenience.
Python has locals() that exposes its locals as a dict. But I don't know if that gives you reference semantics. My experience with Python is rusty (not a reference to Rust).
no. Only Objects are references. primitive data types are just plain old data, values, at least they behave like that.
= on a primitive data type copies the value not a reference
Performance would be even worse than it is if they didn't do at least that.
In Python all types are classes
yeah everything is a object, even classes are objects (instances of metaclasses) 
I believe this is how it is under the hood. but I'm trying to ask if the fact i isn't a reference is observable or just found in language spec and implementation details
Like Java that is presumably semantics.
It has been suggested that ``10.toString()` might eventually be possible in Java... But it won't actually be an instance of a class.
it behaves like plain old data
idk how the jvm specifies them to be implemented but using the language you will observe primitive datatypes to behave like plain old data, just values
wdym?
It's a C++ term, and idk how it's important. I guess you're talking about the assignment behaviour?
But in Java variables of all types have the same behaviour when you reassign them right
lol why you ask if you know it better
sorry, I don't know the answer to the question in the post.
I just don't know what you mean
no like you asked what plain old data means but then corrected me
i meant to ask what you mean by it behaves like POD
I'm trying to ask about by value vs by reference semantics not implementation details about how values look in memory
that is why is said behaviour
implementation does not matter
but it behaves like data, no matter how it is implemented
in what way?
in every way
class Data {
public int d;
public Data(int value) {
d = value;
}
}
int x = 7;
int y = 9;
x = y; // copies the value of y
y = 10;
// x is still 9
Data d1 = new Data(7);
Data d2 = new Data(9);
d1 = d2; // copies the reference of d2 (which is the value of d2 since it is a object)
d2.d = 90;
// d1.d is 90
Data d1 = new Data(7);
Data d2 = new Data(9);
d1 = d2;
d2 = Data(90);
// d1.d is still 9
if we made Data::d final, how would you show the difference?
I'm asking if it's observable that the model 'primitive types are handled by reference too' is wrong
yeah like when you bend a pointer
wdym?
well implementation aside you can imagine that the value of object is their memory address.
so when you do d1 = d2 both point to the same memory address (reference the same object)
but when you assign a new reference to the variable d2 then you obviously did not change the data which was stored at the address d2 pointed to previously but just assigned a whole new reference to the variable
I agree with that
Data *d1 = new Data{7};
Data *d2 = new Data{9};
d1 = d2;
d2 = new Data{90};
like that
yeah
maybe my question is just strange/confusing
what do I lose if I imagine they're not, and that the value of an int variable is also its memory address?
am I just less able to write performant code, or do I also find it harder to write correct code etc?
they are mutable
int x = 5;
++x
it does not create a new int (it is not an object)
you just have an int 4 bytes of raw data in an register or on the stack, and 1 gets add to that value
(in your mental model, the jvm does not have to do that, but it behaves like that)
yes not having primitive datatypes and everything be an object instead like python would cause a massive perfomance loss
everything in python is a pointer to the heap
and every operation creates a new object on the heap, so
a += 10000 in python on an int makes a heap allocation for the new int object and gives the variable the new heap address as its value
pyhton caches small ints but besides that basically every operation on an int in python causes a heap allocation.
In Java, everything is a value type, all primitives, and pointers to objects. Those cannot be changed
For all of those, any modification you do, makes a new one, while the old one still exists
Primitives are technically mutable value types
But you can't mutate them from inside a method, the outside value will never change, neither will the pointer to an object, as Java is pass by value
You can change the object contents in a method though (like adding items to a list)
yes it does
note that you could simulate primitives even with references tho
well
you can't really probe that an int isn't a ref, since even if it was a ref, it could be simulated in a way where you can't detect it
that said, int doesn't have an identity
you can't use it as a lock after all, you can't use it as a generic and you can't use methods on it
yeah basically
the differences are around nullability, synchronized, generics, etc.
but value classes and non-null types will make Integer! pretty much indistinguishable from int
other than the remaining vm intrinsic bytecodes
right now every class has identity and primitives don't
but you've noticed how the usual explanations from folks don't make sense, good job
we got working professionals who don't see that