This question already has answers here:
Does Java have pointers?
(12 answers)
Closed 9 years ago.
Why we are not using the pointer here?
Which concept is used instead of pointer in Java?
Why can't we use pointers in Java?
Because the language designers chose not to include pointers in the language.
Why we are not using the pointer here.
Because the designers of Java thought it was a tricky-to-use and error prone construct.
Which concept is used instead of pointer in Java?
References (which are quite similar to pointers if you disregard from pointer arithmetic).
Keep in mind that all objects you create, you create on the heap (using the new keyword). This fact, together with the fact that there is no "dereference operator" (* in C/C++) means that there's no way to get hold of an object! Since you can't get hold of an object, there's no way you can store an object in a variable. Therefor all variables (except the ones holding primitive types) are of reference-type.
It was a language design decision.
From the sun white paper The Java Language Environment:
Most studies agree that pointers are one of the primary features that
enable programmers to inject bugs into their code. Given that
structures are gone, and arrays and strings are objects, the need for
pointers to these constructs goes away. Thus, Java has no pointer data
types. Any task that would require arrays, structures, and pointers in
C can be more easily and reliably performed by declaring objects and
arrays of objects. Instead of complex pointer manipulation on array
pointers, you access arrays by their arithmetic indices. The Java
run-time system checks all array indexing to ensure indices are within
the bounds of the array.
You no longer have dangling pointers and trashing of memory because of
incorrect pointers, because there are no pointers in Java.
It's good isn't it? You don't have pointers in the C programming sense, the Virtual Machine looks after all that. However, that's not to say you don'f have have similar capabilities. For example, variables for objects are references, when you pass a variable for an object you are passing a reference which is sort of a pointer. You might also use a variable to store the index of an item in an array, that again is a kind of pointer in a programmatical sense.
Everything in Java is accessed only through pointers. Java references are pointers. The creator of java Dr.Gosling says this in his book, "The Java Language Specification" (somewhere around p.40 in one edition).
In fact another book "The Java Virtual Machine" says: "A reference is a pointer to a pair of pointers; one of theses two pointers points to another pointer [...]".
There are marked differences between Java references and C pointers but nevertheless references are pointers.
In Java any reference to a simple type is always by value and any reference
to an object is always a pointer except in cases of special objects.
every object you create using new(); is actually pointer..
XXX a=new XXX();
a is actually a pointer..
It's just you cannot do fancy thing like pointer arithmetic to them like you can in C (for safety reasons).
so actually if you are passing an object, you are passing the pointer to the object (object created by new() resides in heap).
You can access pointer mechanics using java.misc.unsafe, but that's... mmm... unsafe.
Ah, about replacing concept. What aspect are you interested in? Variables are already represented by references to them - that's one point of view. If you need pointers to implement efficient data structures, you, most probably already have one, or there is a library providing that feature, or you can write some native code and call it from java wrapper. Anyway, please define aspects you are interested in and maybe community will give you more detailed answer.
Java follows the principle of call by value. So if you create an object, you will get back a copy of a reference to the created object in the heap space. This copy of a reference is what a variable gets assigned to. If you then use this variable as an argument for a method call, again a copy of that reference is created and used instead. Java never uses references or pointers! Everything in java is a copy. Hence Java follows the call by value principle.
The most difficult thing to manipulate in any programming language is with pointers.
If u just miss something you get lots of errors namely segmentation faults.
Java is one such language providing users the flexibility to do things using CALL BY VALUE .
If you want to change the value of a variable in a C function you pass the address (pointer) of the variable to the function. If you want to use the value of a variable in a function and do not wish to change its value, you pass the name (reference) of the variable to the function. Many programmers never used pointers for any thing else, like linked lists and b trees. C pointers and structures can make some applications infinitely easier. Structures unlike arrays can contain different types of variables and grouping them together makes life easier. Structures in a linked lists contain pointers (addresses to the next link in the list and also to the previous link if the list is double linked. This can make sorting a breeze.
A link in the list can also contain pointers to different structures which allow you to associate the linked lists of different materials or conditions with each link in the first list.
Since the memory is allocated where and as needed rather than being dimensioned as in an array, it gives you tremendous flexibility.The main application I have used this for is calculating the cost of projects to bid jobs.
This flexibility demands close attention to details and no holds barred debugging.
Related
I am taking data structures and analysis. We have gone over how assignment and comparisons of object types is much slower than assignment and comparisons for basic types, such as int.
I recall learning C (all those almost thirty years ago) and how pointers in C are (or were) integer calls. Is Java similar today, is a reference to an instanced object internally an integer address of memory, and as such are comparisons such as
if (MyObject != null) {...}
an integer operation within the framework?
I hope my question is clear. I've been researching around and I can't find a clear answer of how Java manages its dynamic memory.
The short answer is yes, a reference to an object is stored as pointer like it is in C.
I am not sure what you mean by stored as "integer", but if what you want is to do some operation on them like you can do in C (e.g. add integer to a pointer, etc.), then you can't with Java.
For the rest, it's pretty much the same except that it is handled by Java.
JLS 4.3.1 specifies that a reference to an object is stored as pointer:
The reference values (often just references) are pointers to these
objects, and a special null reference, which refers to no object.
The Java language specification specifies that
In the Java programming language arrays are objects (§4.3.1), are dynamically created, and may be assigned to variables of type Object (§4.3.2). All methods of class Object may be invoked on an array.
So, considering arrays are objects — why did the Java designers make the decision not to allow inherit and override from it, for example, toString() or equals()?
The current syntax wouldn't allow creating anonymous classes with an array as the base class, but I don't think that was the reason for their decision.
Java was a compromise between non-object languages and very slow languages of that time where everything was an object (think about Smalltalk).
Even in more recent languages, having a fast structure at the language level for arrays (and usually maps) is considered a strategic goal. Most people wouldn't like the weight of an inheritable object for arrays, and certainly nobody wanted this before JVM advances like JIT.
That's why arrays, while being objects, weren't designed as class instances ("An object is a class instance or an array"). There would be little benefit in having the ability to override a method on an array, and certainly not a great-enough one to counterbalance the need to check for the right method to apply (and in my opinion not a great-one enough to counterbalance the increased difficulty in code reading, similar to what happens when you override operators).
I came across UNDER THE HOOD - Objects and arrays which explains almost anything you need to know about how JVM handles arrays. In JVM, arrays are handled with special bytecodes, not like other objects we are familiar with.
In the JVM instruction set, all objects are instantiated and accessed
with the same set of opcodes, except for arrays. In Java, arrays are
full-fledged objects, and, like any other object in a Java program,
are created dynamically. Array references can be used anywhere a
reference to type Object is called for, and any method of Object can
be invoked on an array. Yet, in the Java virtual machine, arrays are
handled with special bytecodes.
As with any other object, arrays cannot be declared as local
variables; only array references can. Array objects themselves always
contain either an array of primitive types or an array of object
references. If you declare an array of objects, you get an array of
object references. The objects themselves must be explicitly created
with new and assigned to the elements of the array.
Arrays are dynamically created objects, and they serve as a container that hold a (constant) number of objects of the same type. It looks like arrays are not like any other object, and that's why they are treated differently.
I'd like to point out this article. It seems as though arrays and objects follow different opcodes. I can't honestly summarize it more than that however it seems, arrays are simply not treated as Objects like we're normally used to so they don't inherit Object methods.
Full credits to the author of that post as it's a very interesting read, both short & detailed.
Upon further digging into the topic via multiple sources I've decided to give a more elaborate version of my previous answer.
The first thing to note that instantiation of Objects and Arrays are very different within the JVM, their follow their respective bytecode.
Object:
Object instantiation follows a simple Opcode new which is a combination of two operands - indexbyte1 & indexbyte2. Once instantiated the JVM pushes the reference to this object onto the stack. This occurs for all objects irrespective of their types.
Arrays:
Array Opcodes (regarding instantiation of an array) however are divided into three different codes.
newarray - pops length, allocates new array of primitive types of type indicated by atype, pushes objectref of new array
newarray opcode is used when creating arrays that involve primitive datatypes (byte short char int long float double boolean) rather than object references.
anewarray - pops length, allocates a new array of objects of class indicated by indexbyte1 and indexbyte2, pushes objectref of new array
anewarray opcode is used when creating arrays of object references
multianewarray - pops dimensions number of array lengths, allocates a new multidimensional array of class indicated by indexbyte1 and indexbyte2, pushes objectref of new array
multianewarray instruction is used when allocating multi-dimensional arrays
Object can be a class instance or an array.
Take from Oracle Docs
A class instance is explicitly created by a class instance creation expression
BUT
An array is explicitly created by an array creation expression
This goes hand in hand with the information regarding the opcodes. Arrays are simply not developed to be class interfaces but are instead explicitly created by array creation expression thus naturally wouldn't implicitly be able to inherit and/or override Object.
As we have seen, it has nothing to do with the fact that arrays may hold primitive datatypes. After giving it some thought though, it isn't very common to come across situations where one might want to toString() or equals() however was still a very interesting question to try and answer.
Resources:
Oracle-Docs chapter 4.3.1
Oracle-Docs chapter 15.10.1
Artima - UnderTheHood
There are many classes in standard java library that you cannot subclass, arrays aren't the only example. Consider String, or StringBuffer, or any of the "primitive wrappers", like Integer, or Double.
There are optimizations that JVM does based on knowing the exact structure of these objects when it deals with them (like unboxing the primitives, or manipulating array memory at byte level). If you could override anything, it would not be possible, and affect the performance of the programs very badly.
I'm in the process of learning Java and can't help but wonder how exactly Java passes function parameters and return values. I've done some search and found that Java only passes Objects by value. However, some people challenge this; they claim that when handling Complex Data Types (not Primitive like e.g. int) it only passes a pointer.
Does this mean that whatever changes are made to the local object affect the original one? Is there any way to pass "PURELY" by value (i.e. make a hard copy of an Object)?
Furthermore, what is true about the return value? For example, we use accessors (or getter functions - I'm not completely sure how they are called) to protect the private Attributes of an ADT from being changed to "illegal" values. If Java passes the Pointer, then whatever changes I make to the returned Object of an Accessor Function also affect the actual Attribute, if it isn't a Primitive Data Type, don't they?
Could anybody please help me clarify these concepts?
Thank you in Advance! :D
The key is to understand that Java passes everything by value. And this is also true for objects: It passes the pointers by values. So, it does not create a copy of the object, but of the reference.
The same goes for returning. So, yes, your thinking is right: you can modify the attributes (called class members) objects because they get returned in the form of a pointer. That is the reason why (if needed) someone could choose to design a class whose objects are is not modifiable once it is created.
I've done some search and found that Java only passes Objects by
value.
There is your confusion. You cannot "pass objects" in Java, because objects are not values in Java. The only types in Java are primitive types and reference types (references are pointers to objects). So the only values you can manipulate in Java are primitives and pointers to objects. All types are passed or assigned by value.
I want to have an object that allows other objects of a specific type to register themselves with it. Ideally it would store the references to them in some sort of set collection and have .equals() compare by reference rather than value. It shouldn't have to maintain a sort at all times, but it should be able to be sorted before the collection is iterated over.
Looking through the Java Collection Library, I've seen the various features I'm looking for on different collection types, but I am not sure about how I should go about using them to build the kind of collection I'm looking for.
This is Java in the context of Android if that is significant.
Java's built-in tree-based collections won't work.
To illustrate, consider a tree containing weak references to nodes 'B', 'C', and 'D':
C
B D
Now let the weak reference 'C' get collected, leaving null behind:
-
B D
Now insert an element into the tree. The TreeMap/TreeSet doesn't have sufficient information to select the left or right subtree. If your comparator says null is a small value, then it will be incorrect when inserting 'A'. If it says null is a large value, it will be incorrect when inserting 'E'.
Sort on demand is a good choice.
A more robust solution is to use an ArrayList<WeakReference<T>> and to implement a Comparator<WeakReference<T>> that delegates to a Comparator<T>. Then call Collections.sort() prior to iteration.
Android's Collections.sort uses TimSort behind-the-scenes and so it runs quite efficiently if the input is already partially sorted.
Perhaps the collections classes are a level of abstraction below what you're looking for? It sounds like the end product you want is a cache with the ability to iterate in a user-defined sort order. If so, perhaps the cache interface in the Google Guava library is close enough to what you want:
http://code.google.com/p/guava-libraries/source/browse/trunk/guava/src/com/google/common/cache/Cache.java
At a glance, it looks like CacheBuilder in that package doesn't allow you to build an implementation with user-defined iteration order. However, it does provide a Map view that might be good enough for your needs:
List<Thing> cachedThings = Lists.newArrayList(cache.asMap().values());
Collections.sort(cachedThings, YOUR_THING_COMPARATOR);
for (Thing thing : cachedThings) { ... }
Even if this isn't exactly what you want, the classes in that package might give you some useful insights re: using References with Collections.
DISCLAIMER: This was a comment but it got kinda big, sorry if it doesn't solve your problem:
References in Java
Just to clarify what I mean when I say reference, since it isn't really a term commonly used in Java: Java does not really use references or pointers. It uses a kind of pseudo-reference that can be (and is by default) assigned to the special null instance. That's one way to explain it anyway. In Java, these pseudo-references are the only way that an Object can be handled. When I say reference, I mean these pseudo-references.
Sets
Any Set implementation will not allow two references to the same object to be included in it since it uses identity equality for this check. That violates the mathematical concept of a set. The Java Sets ignore any attempt to add duplicate references.
You mention a Map in your comment though... Could you clarify what kind of collection you are after? And why you need that kind of equality checking within it? Are you thinking in C++ terms? I'll try to edit my answer to be more helpful then :)
EDIT: I thought that might have been your goal ;) So a TreeSet should do the trick then! I would not get concerned about performance until there is a performance issue. Simplicity is fantastic for readability, maintenance and preventing bugs. If performance does become a problem, ideally you should profile your code and only optimize the areas that are proven to be the problem.
Is there any reason why an array in Java is an object?
Because the Java Language Specification says so :)
In the Java programming language arrays are objects (§4.3.1), are dynamically created, and may be assigned to variables of type Object (§4.3.2). All methods of class Object may be invoked on an array.
So, unlike C++, Java provides true arrays as first-class objects:
There is a length member.
There is a clone() method which overrides the method of the same name in class Object.
Plus all the members of the class Object.
An exception is thrown if you attempt to access an array out of bounds.
Arrays are instanciated in dynamic memory.
Having arrays be objects means that you can do operations with them (e.g., someArray.count('foo')) instead of just doing it against them (e.g., count(someArray, 'foo')), which leads to more natural syntax.
Another point is that objects are mutable and are passed by reference. In arrays there aren't any fields/methods that you can use to change "properties" of the array, but you sure can mutate the element values. And the benefits of passing arrays by reference are pretty obvious (though functional programmers probably wish Java had immutable lists passed by value).
Edit: forgot to mention. In the period before autoboxing, it was helpful to be able to store arrays in collections, write them to ObjectStreams etc.
Probably because they wanted to get as close as possible to making everything an object. Native types are there for backward compatibility.
So that they get all the benefits thereof:
getHashCode()
toString()
etc.
And arrays aren't 'primitive', so if they can't be primitive, they must be objects.
I'm not sure about the official reason.
However, it makes sense to me that they are objects because operations can be performed on them (such as taking the length) and it made more sense to support these operations as member functions rather than introduce new keywords. Other operations include clone(), the inherited operations of object, etc. Arrays are also hashable and potentially comparable.
This is different from C (and native arrays in C++), where your arrays are essentially pointers to a memory offset.