I was wondering if it was possible to get some String value of an Object to access that Object on the same machine (same RAM) or the same VM via that particular String.
e.g.
Object objA1 = new Object();
System.out.print(objA1.adress); => output: d146a6581ed9e
Object objExt = Object.buildFromMemoryAdress("d146a6581ed9e");
I hope you understand what I'm trying to understand.
EDIT: I found in
http://javapapers.com/core-java/address-of-a-java-object/#&slider1=1
a Class that allows me to get the String of the logical address of an instance on the (VM?) memory: sun.misc.Unsafe
I think I can also use Unsafe to retrieve an Object from the (restricted to the VM?) memory.
If not possible like this, how would I do it, and since it's out of curiosity are there any other languages (especially high end) that allow direct memory access like this?
It is incorrect to assume that the number that you see in the toString() result is the memory address.
It is, in fact, the object's hash code. If the object isn't modified, its hash code remains constant. However, its memory address can change at any time: a compacting garbage collector can decide to move the object in memory whenever it feels like it.
Absolutely not. In fact, it's clearly impossible, given that you can obviously have two different objects whose toString() methods return the same string. As a simple example:
Integer a = new Integer(10);
Integer b = new Integer(10);
Object x = Object.buildFromToString("10");
What should x refer to? The same object that a refers to, or the same object that b refers to?
toString() is not meant to return an object identifier - it's just meant to return some sort of textual representation of an object. Just because the default implementation returns something which looks a bit like an identifier shouldn't be taken as an indication that it should be used as an identifier.
If you want to store some way of accessing an object at some other point in time, I suggest you just store a reference to it as an Object variable.
No, this is not possible. Java objects are only accessible if you have a reference to those objects. What you can do is store your objects in a Map<String, Object> under a given name, and get back the reference of the object from its name, using the map.
Related
Can we create an Immutable object, that contains a mutable object? Is is possible?
please make me more clear about this.
Thanks in advance.
Yes we can.
Take for example the code from java.lang.String:
/** The value is used for character storage. **/
private final char value[];
Obviously arrays are mutable because we can easily change their content like this:
value[0] = '&';
However String is still immutable. That is, once created, its contents will never change. How does that happen?
Because even though value is mutable, there's no "regular" way for the user of String to modify it:
value is declared private final. And String itself is final, meaning no subclass.
There's no setter methods. Nor any methods that modifies value.
We can create a string from a char array, but the char array is copied inside the constructor, so modifying the original array would have no effect to the newly created string.
The value field could also be shared by multiple String instances, but as long as it's not leaked, it's safe.
We can convert a string back to a char array, but again, its a copy.
So the answer is yes, if we follow a design strategy carefully.
In Java (and as far as I know all other mainstream languages with a const / final / readyonly / val etc keyword) an "immutable" object can contain references to mutable objects. For a deeper dive into immutability see this paper - the quick takeaway is that there are unofficial Java extensions that allow you to specify that e.g. an immutable object can only contain references to immutable objects, e.g. Javari or Joe3 or OIGJ
Objects in Java never really contain other objects--not like in C or in some other programming languages. Even the so-called "container" classes really just contain references to other objects.
An immutable object can refer to any other objects, mutable or immutable.
You can't change which other objects an immutable object refers to, but you can change the other objects if they are mutable.
Edit: This depends somewhat on what you mean by "immutable." As another person pointed out, sometimes "immutable" is defined as a form of "shallow" immutability - i.e. constant references to mutable objects are allowed. I'm not fond of this definition myself. Some people might disagree with me here (and hopefully no one will downvote b/c of a difference of opinion), I think it's much clearer to define "immutability" as "having no mutable state of any kind."
Under this definition, the answer to your question is **no* because if it refers to mutable objects that gives it mutable state, which would make the object itself mutable.
I think it's important at this point to distinguish between a constant reference or pointer and an immutable object. For example, the following code is a constant reference to a constant object:
private final string abc = "John";
Note that you can't modify the state of "abc" (i.e. that particular string will always be "John" - you can't change it to "Johnny" later, you'd need to create a new string. Also, you can't replace "John" with a new string (i.e. the variable "abc" itself will always refer to that string).
The following code is a mutable reference to an immutable object:
public string abc = "John";
(By the way, I do realize you should use a property here instead).
If you were to later do:
abc = "Johnny";
you'd be allowed to do that. In this case, you're changing the object that the variable "abc" is referring to, not the original string. The string "John" will always have that value as long as it exists.
However, consider the following object:
public class Defg
{
public int Count;
public Defg(int Count)
{
this.Count = Count;
}
}
Clearly, this is a mutable class (because you can change the value of "Count").
You can do the following:
// Mutable reference to a mutable object. Note: "Count: 1" is a bit of C# syntax that just means that the "Count" parameter is set to 1. It's not strictly necessary here, I just added it for clarity.
public Defg Mutable = new Defg(Count: 1);
// Constant reference to a mutable object
public final Defg ConstReference = new Defg(Count: 1);
Note that the following is all perfectly valid:
Mutable = new Defg(Count: 10);
Mutable.Count = 4;
ConstReference.Count = 3;
However, you cannot do the following:
ConstReference = new Defg(Count: 3);
Note, in particular, that Defg can't possibly be an immutable object because you can change its state.
To summarize:
a) It's perfectly possible to have either a mutable reference to a constant object or a constant reference to a mutable object - the mutability of the reference to the object has nothing to do with whether the object itself is mutable and vice versa.
b) Whether an object that refers to mutable objects can still be considered immutable depends on your definition of "immutable." In my opinion it can't because referring to a mutable object gives it mutable state; it would be confusing/misleading at best to describe that as immutable.
I think that it's possible. But access modifier of variable which refers to mutable object must be final.
I've started reading about Project Valhalla and there is something I really don't understand and it's the Value Types.
This is what I understand:
1) Are objects that can't be compare it as reference?
final ValueType a = new ValueType();
final ValueType b = a;
System.out.println(a==b); returns false????
In Google AutoValue code example, it states
if(o == this){return true;}//equals method implementation what is this? I am comparing references here right?
2) According to Wikipedia, highly-efficient small 'objects' without inheritance. What do Small Objects? and Without inheritance mean?
Is this not possible using VT?
public final class ValueType extends Any //is this not possible??
3) Why are they used? Which scenario would be used and how would it be used.
4) According to Google AutoValue Library, in a nutshell, a value-typed object is an object without an identity, i.e. two value objects are considered equal if their respective internal state is equal. My question is: do they have state and should they implement equals and hashcode. What does object without an identity mean?
5) Is this assertion correct?
public static void main(final String[] args)
{
final Test clazz = new Test();
final AutoValue value = new AutoValue("Java Belongs to SUN");//Constructor Name
clazz.mutate(value);
System.out.println(value.getName()); //would print: Java Belongs to SUN??
}
private void mutate(final AutoValue value){value.setName("Java now is part of Oracle Corporation");return;}
If it is so, would JVM gain memory not tracking this Objects or Values between methods calls?
Project Valhalla is part of initial Project of Java 10 would be ready in 2018 or so.
Your final assertion is correct. The ValueType variables are entirely copied when passing them as a parameter to a function, rather than typically just getting a copy of the reference to an object. This allows you to treat a small object as if it were a value type like int or boolean.
1) Under Project Valhalla, two ValueTypes would be compared by fields directly, even for == checks, much like primitive types. With Google's AutoValue types, you would never use == directly, because that would still be an identity check.
2) Small Objects means that this should be used for objects that only have a few fields, as the whole content of the object is going to be copied repeatedly. Large objects would be better served with passes by reference.
Without Inheritance means that you won't be able to use polymorphism for Value Type objects. Because Value Types are meant to be stored directly, like primitive values, they don't include any class information, so the JVM must always be able to infer what the object is from the program itself, instead of from any information on the object. For example, an Integer field could be a Value Type member, while a Number field would have to still be by reference.
3) They are used to avoid the dereference penalty normally required for accessing an object's members. For example, with a List of Points, each Point is actually a reference to the x and y values in memory, so iterating over the list will involve many dereferences. If the Points were stored directly in the list, this would be avoided.
4) Object Without an Identity means that all that matters about the object is its value. Just as an int valued 1 should be the same as all other ints valued 1, and all Strings "hello world" are equal to all other Strings "hello world", whether or not they are actually the same object. By contrast, two ArrayLists that are both empty, while at the time equal, have identity, because they are mutable, and adding an element to one list must be distinct from adding an element to the other list.
5) Under Project Valhalla, the AutoValue, if it is a Value Object, would be immutable, so there would be no setName method to call. It would be similar to how you can never mutate 1 into 2, you instead modify where a 1 is located so that a 2 is there instead.
Source: http://cr.openjdk.java.net/~jrose/values/values-0.html
The other answers are fine, but there is one other perspective about the core point of value objects: they give you stack semantics.
Meaning: before project Valhalla, you either have primitive "objects" and
reference objects. The first ones can exist on the stack, but real objects only live on the heap.
Value objects will change that. You can have "real" objects - but their data only resides on the stack. This means that you do not have a reference (and therefore cost for de-referencing) anything - just like primitive types, the value is directly placed on the stack. But now that value can be more than just a single int, long, ... - you can have a real, "complex" object - but all its data is directly there on the stack.
And because of that, you can nicely do a == b now - because now you are no longer comparing references that point to the heap - but a and b directly have their corresponding values.
UPDATE 2019/2020, Build 14-valhalla+4-55 (2019/8/30)
Inline Class is the new name of "Value Type". According to current project state Inline Classes don't support inheritance but are able to extend interfaces. Following statement is legal:
public inline class MyInlineClass extends SomeJavaInterface {}
They do have equals, hashcode (and toString) methods. "==" operation and equals (default implementation) are same for simple case, where only Inline Classes and primitive fields are involved. But it is not true in general.
It becomes messy, if you add a classic Java Object (including String and Array) as a field inside of Inline Class. In this case "==" operation most probably won't work as expected anymore and you have to fallback to classic custom equal implementation.
Inline objects are immutable and don't support clone (clone makes no sense).
A possible usecase for Inline Classes would be complex numbers or matrix algebra, which is essential for neural networks algorithms of artificial intelligence systems.
I have two classes(f.e. Car and Bicycle). Objects of both classes are sent to management layer, where they are used.
I send every object to that layers by calling layerHandler.objectReceived(object);
LayerHandler then need to store this object in its HashMap (im using Object because objects which will be stored there are not same type...(Car and Bicycle))
LayerHandler has other method called actionFired(String message, Object object);
Second parameter 'object' belongs to Car or Bicycle class and is already stored in LayerHandler's HashMap. When this method occures, I need to find related object which is stored in HashMap.
Right now Im using object.toString() as key value for hashmap. Both type of objects use defaut toSting() method which is not overriden.
Im not going to show whole structure of my project here, but Im using HashMap for a reason. (I know ArrayList get(Object obj) method would be nice here, but I must use HashMap)
I need to know, whether toString() will always returns same value which wont change over time so I will be able to use that as a key for my HashMap.
If you haven't overridden .toString() then, for a given instance, it will continue to return the same string throughout the instance's life. But it is quite possible that once this instance has been garbage collected, another instance of this class or even another class will be allocated to the same block of memory and will return the same string as this one did.
But rather than using a String as the key, you would be better off changing actionFired to give you the object rather than a string representation. It's very fragile to do it like this, and if your implementation changes later, it might all break.
There is no restrictions to have different types of keys in the HashMap, if you provide correct implementation of hashCode+equals.
You should override hashCode+equals methods in your key-object classes (Car, Bicycle, ...)
Use these objects directly as keys in your HashMap
Basically i want to add students to a class list. Assuming i have the following code
public class ClassList {
//Constructor methods...
private Student [] studList = new Student [20];
public boolean addStudent (Student newStudent)
{
studList[14] = newStudent;
}
}
Does studList[14] add a reference to newStudent object or copies that object into the studList[14] student object?
As far as i understand newStudent object will get deleted when the method addStudent() is called a second time. So studList[14] will point to null then? What if i want studList[14] to persist throughout the code execution?
Sorry if it is hard to understand, i do not know how to explain my query easier...
There's one fundamental rule in Java that you have to wrap your head around:
The only way you can access an object is via its reference. And the only values that variables can hold are references(*). That's true for local variables, parameters, instance fields and static fields: they all are the same in this respect.
The object itself is never "contained" in a variable.
This directly leads to the answer to your first question:
The reference is copied into the array (as an array can only hold references(*), never objects).
This also mean that "newStudent being deleted" is not actually a big deal: it's just another reference to the same object, and if it goes away nothing much happens.
Now, if all references to a given object are removed (or no longer reachable), then the object itself becomes eligible for garbage collection, but that's not a bad thing, because you could not access it anymore anyway.
(*) ... or primitive values, but we'll ignore those for this dicussion.
The assignment doesn't copy the object. It just adds a reference to the object into the array.
An object gets deleted by the garbage collector after there are no more references to it anywhere. You don't need to worry too much about this process, because it's kind of invisible most of the time; and once there are no references to an object, you couldn't have used it anyway.
Perhaps you want to be able to pass in an int to your method, to tell it which entry in the array to set, instead of always setting entry number 14?
You should have a look at the JLS about types, values and variables:
The values of a reference type are references to objects.
If there is no remaining reference (aside weak ones) to an object it will be garbage-collected out of the heap.
If you call two times: addStudent(new Student());
the first Student object created is qualified for GC since you have no other reference variable "pointing" to the object.
Are arrays in Java pass by reference or pass by value?
Suppose I have an array called data that contains objects of some type. Now let us suppose that I pass and store that array in class A and then I pass it to class B and class B changes one of the entries of the array. Will class A's version of the array change? Does it matter if this was an array of primitives (such as int) instead? What about ArrayLists?
Everything in Java is pass-by-value. However, if you're passing a reference, it's the value of the reference.
Since Java methods can't reach into the caller's stack to reassign variables, no method call can change the identity of a reference (address) there. This is what we mean when we say Java is not pass-by-reference. This contrasts with C++ (and similar languages), which allows this in some cases.
Now let's look at some effects.
If I do:
Object[] o = ...
mutateArray(o);
the contents can be different afterwards, since all mutateArray needs is the address of an array to change its contents. However, the address of o will be the same. If I do:
String x = "foo";
tryToMutateString(x);
the address of x is again the same afterwards. Since strings are immutable, this implies that it will also still be "foo".
To mutate an object is to change the contents of it (e.g. successfully changing the last element of o, or trying to change the last letter of "foo" to 'd'). This should not be be confused with reassigning x or o in the caller's stack (impossible).
The Wikipedia section on call by sharing may shed additional light.
Arrays, like all other objects, are pass by reference (technically, you are passing a reference by value, but from the objects point of view, it is passed by reference). If you pass an array to a method and the method changes the array, the caller will see the changes. If you want to avoid having your copy modified, you need to copy it yourself. It doesn't matter whether the array contains primitives or objects. In general, this is the behavior you want, since passing by value would involve unnecessarily copying the (potentially large) array every time you use it as an argument.
The Jist of it is - everything in Java is passed by reference, unless it is a primitive.