I'm reading section 12.6.1 of Java SE specs and it said:
Optimizing transformations of a program can be designed that reduce the number of objects that are reachable to be less than those which would naively be considered reachable. For example, a Java compiler or code generator may choose to set a variable or parameter that will no longer be used to null to cause the storage for such an object to be potentially reclaimable sooner.
Another example of this occurs if the values in an object's fields are stored in registers. The program may then access the registers instead of the object, and never access the object again. This would imply that the object is garbage. Note that this sort of optimization is only allowed if references are on the stack, not stored in the heap.
The relevant code is:
class Foo {
private final Object finalizerGuardian = new Object() {
protected void finalize() throws Throwable {
/* finalize outer Foo object */
}
}
}
My question is what kind of JVM would ever store finalizerGuardian in the stack not the heap and why?
The code example is for illustrating the last sentence of your cited text, “Note that this sort of optimization is only allowed if references are on the stack, not stored in the heap” and it is a bit odd that you ripped it off the explaining text:
For example, consider the Finalizer Guardian pattern:
class Foo {
private final Object finalizerGuardian = new Object() {
protected void finalize() throws Throwable {
/* finalize outer Foo object */
}
}
}
The finalizer guardian forces super.finalize to be called if a subclass overrides finalize and does not explicitly call super.finalize.
If these optimizations are allowed for references that are stored on the heap, then a Java compiler can detect that the finalizerGuardian field is never read, null it out, collect the object immediately, and call the finalizer early. This runs counter to the intent: the programmer probably wanted to call the Foo finalizer when the Foo instance became unreachable. This sort of transformation is therefore not legal: the inner class object should be reachable for as long as the outer class object is reachable.
So the code example illustrates a restriction. The “optimizing transformations” mentioned by the specification includes Object Scalarization applied after Escape Analysis has proven that an object is purely local, in other words, the code under optimization spans the entire lifetime of the object.
But it doesn’t need such local objects. As the specification already mentioned, optimized code may keep an object’s fields in CPU registers without the need to re-read them, thus, does not need to keep the object reference anymore. Likewise, a reference variable still in scope may be unused. If that reference was the only reference to an object, removing it from the optimized code allows earlier garbage collection.
Both scenarios would still allow a Foo instance to get eliminated or collected earlier. This in turn would allow the earlier collection of the object (not anymore) referenced by finalizerGuardian. But that doesn’t counteract the intention of this restriction. The specification restricts the optimization to not allow the inner object to get collected earlier than the outer object, but there is no problem in collecting both together, including earlier than naively expected.
Generally, arbitrarily large object graphs may get collected in a single garbage collection cycle, perhaps earlier than naively expected, or even get optimized away completely.
a classic example for such kind of optimization (escape analysis) is a calculation with Point class:
class Point {
double x;
double y;
public Point(final double x, final double y) {
this.x = x;
this.y = y;
}
double length() {
return Math.sqrt(x * x + y * y);
}
static double calc() {
double result = 0;
for (int i = 0; i < 100; i++) {
// this allocation will be optimized
Point point = new Point(i, i);
result += point.length();
}
return result;
}
}
after inlining this new will be not needed because we can extract all fields to local variables like
Point point = new Point(i, i);
double x = point.x;
double y = point.y;
result += Math.sqrt(x * x + y * y);
->
Point point = new Point(i, i);
double x = i;
double y = i;
result += Math.sqrt(x * x + y * y);
now it's obvious that new Point(i, i) is useless and JIT just remove this line.
Note that the allocation was on stack i.e. in a local variable. If it was in a field we'd not be able do that optimization because it's stored in the heap.
That how it works.
about your code snipped: the finalizerGuardian will always in the field (stored in the heap) and JVM can do nothing with this allocation. Furemore if the class Point from the example above contains such field, i think escape analys is not able to remove the allocation because it might change the original behaviour.
Related
In Java, having a nested static class Human, I'm wondering if after cleanup of the map variable can make it available for garbage collected. At the moment just before doSomeCode() I called System.gc() and added Thread.sleep(60000) to wait for garbage collector to pick up unreferenced map contents, but no way - it seems map lives in a program unless it is going to finish. My problem is that I need to free up memory because otherwise will get OutOfMemoryError.
What do you think prevents map property of Human class from being recycled? Is it because the Human class is static and thus all its members can not be garbage collected?
import java.util.List;
import java.util.ArrayList;
import com.carrotsearch.hppc.IntObjectMap;
import com.carrotsearch.hppc.IntObjectOpenHashMap;
public class TestNestedStaticClass {
public static class Human {
String name = null;
List<Human> children = null;
// some data about family members
IntObjectMap<int[]> map = null;
public Human(String name) { this.name = name; }
}
public static void main(String[] args) {
final List<Human> family = new ArrayList<Human>();
for (int i = 0; i < 1000; i++) {
// create and get the family member
family.add(new Human("givenName"));
Human h = family.get(i);
// create map and add some data
h.map = new IntObjectOpenHashMap<int[]>();
for (int j = 0; j < 100; j++) {
int[] array = new int[1500];
h.map.put(j, array);
}
}
// ...
// at some point we want to free the memory occupied by
// family.get(i).map for all i from 0 to 1000, so we do:
for (int i = 0; i < 1000; i++) {
// get the family member
Human h = family.get(i);
// explicitly remove references from the map
for (int j = 0; j < 100; j++) {
h.map.remove(j);
}
// cleanup
h.map.clear();
h.map = null;
}
// ...
doSomeCode();
}
}
From the point where you write: h.map = null;, the map becomes eligible for GC (the removes and clear are technically not necessary).
The reason why you don't see it being GC'ed is possibly due to the fact that you run all that code within the same method, and the GC does not have to collect local variables until the method exits.
If you try to split it in several method it will help the GC (which will get rid of the local variables once the methods exit).
See also this post.
ps: I assumed that you don't have any references to the content of the map or the map itself anywhere else!
The fact that the Human class is static means nothing - and even if the map variable was static, setting it to null frees up the object content for garbage collection.
If you are running into OutOfMemoryErrors, and you are certain the map contents are the cause, then there must be lingering references to the data somewhere. For example, if I do this:
human.map.put(0, new int[10000]);
something.thing = map.get(0);
human.map.remove(0);
human.map = null;
Note that a reference to the int[10000] still remains in memory, #something.thing. Cleaning up the map is only part of the work needed to free up the array for garbage collection.
Note that inner static classes are indeed top classes but just inside a class, so the GC rules to collect their instances are the same rules that GC applies on a common class instance.
There is no need to sleep after System.gc() - the gc method doesn't return until the garbage collector is finished.
An instance of a static inner class is treated the same as an instance of any other class for purposes of garbage collection. You are correctly freeing the map elements of your Human classes (although it's overkill to call map.remove() and map.clear() and map = null - only map = null is needed)
It looks like you are using all primitive data types. This might be a problem, this is just a theory, and I haven't tested it, but it might be worth a try.
Instead of using an array of int's ( int[] ), try using an ArrayList. This should create objects which can be garbage collected, primitive data types are created on the stack not on the heap of objects, therefore they aren't subject to garbage collection?
NOTE: I put a question mark, because I am not positive, someone can confirm or reject my theory.
THEORY REJECTED :( , LEAVING AROUND FOR OTHERS TO READ
1) Been a while since I programmed in Java but my guess is the static objects/variables live on in a special place during whole execution of the program.
2) Calling GC explicitly doesn't ensure the objects will be deleted. You simply call the GC and it decides itself (and you cannot really affect this behavior).
I know this issue has been addressed many times - but my Java/C++ knowledge is so weak I can barely understand the answers :-( ... what I'd really like is just a super simple example.
In C++ I could write the following:
void func()
{
int x = 3;
add_one(x);
// now x is 4.
}
void add_one(int &var)
{
var++;
}
What I'd like to see now is the simplest way to achieve the same effect with java.
You can't directly. The closest you can get is to put the value in an object, and pass the reference (by value, so the reference gets copied) into the method.
void func()
{
int x = 3;
int[] holder = [x];
add_one(holder);
// now holder[0] is 4. x is still 3.
}
// container here is a copy of the reference holder in the calling scope.
// both container and holder point to the same underlying array object
void add_one(int[] container)
{
container[0]++;
}
Here I use an array, but the wrapper can be any object.
In java method arguments are pass-by-value, and can't be changed in the function. You must wrap the int - or any other primitive type - in an Object or an array. Passing an Object or an array as a method argument passes a reference which can be used to modify the object.
Java already has Object based wrappers for primitive types, e.g. Integer, but these are immutable by design. Some libraries provide mutable versions of these wrappers; you can also create your own:
public class MutableInt
{
private int val;
public MutableInt(int val)
{
this.val = val;
}
public void setValue(int newVal)
{
this.val = newVal;
}
public int getValue()
{
return this.val;
}
}
void func()
{
int x = 3;
MutableInt wrapper = new MutableInt(x);
add_one(wrapper);
}
void add_one(MutableInt arg)
{
arg.setValue(arg.getValue() + 1);
}
You cannot do this. Java is only pass by value. Primitives are obvious, but the thing that's passed for objects is a reference, not the object itself.
As you can see from the other answers, Java is purely pass by value. Objects are passed by what some call "value-reference". Since an object in java is simply a pointer reference, you can think of the "value" as the address where the object lives on the heap. So when you make a method call, you're copying the "value", aka address, to the method parameter:
Object x = new Object();
foo(x);
During object creation
Heap --> allocate Object (5000)
Variable Declaration
Stack --> allocate local variable (1000)
Variable Assignment
Stack address 1000 set to 5000 (to point to object instance)
So you can see that there are two separate memory allocations here. The "value" of the variable is considered to be it's address on the heap.
Method Call
Stack --> allocate method parameter 8000
Stack address 8000 set to same value as passed parameter 5000
This is why if you reassign an object instance in a method, it does not propagate back to the caller. You would have changed the heap location at stack location 8000. And the calling method's stack location 1000 still has the value 5000 (the original object instance).
Think of it like this in C:
void method(myobject * obj);
You can certainly change fields of "obj", and you can do this locally:
obj = new myobject();
But the caller will still see the original value it passed.
Java has no analog to the & reference operator.
And there are built in classes which can be used for the your purposes. AtomicInteger, AtomicLong, etc... are mutable, though you may suffer a performance hit due to synchronization involved.
I would recommend a generic ValueHolder class to account for all situations where you want to simulate pass by reference:
public class ValueHolder<T> {
private T value;
// getter/setter/constructor
}
Java allows copy by reference for objects and copy by vlaue for primitive types (int,float,etc..). This is so by default and is not subject to change. If you need to change the value of an int inside a function, then you can use the class Integer for example
public int getOneMore(int val) {
return val + 1;
}
I am developing an app that creates a large number of small, immutable Java objects. An example might be:
public class Point {
final int x;
final int y;
final int z;
.....
}
Where it is likely that many instances of Point will need to refer to the same (x,y,z) location.
To what extent does it make sense to try to cache and re-use such objects during the lifetime of the application? Any special tricks to handle this kind of situation?
When it becomes a problem. Otherwise you're just creating a useless layer of abstraction.
Either way, you could easily implement this with a PointFactory that you call to get a Point, which always returns the same object instance for any given x, y and z. But then you have to manage when the points should be removed from cache because they wont be garbage collected.
I say forget about it unless it's an actual issue. Your application shouldn't depend on such a caching mechanism, which would allow you to add it in later if necessary. So maybe just use a factory that returns a new point instance very time for now.
public class PointFactory{
public static Point get(int x, int y, int z){
return new Point(x, y, z);
}
}
The problem you are likely to have is making the object pool light weight enough to be cheaper than just creating the objects. You want to the pool to be large enough that you get a fairly high hit rate.
In my experience, you are likely to have problems micro-benchmarking this. When you are creating a single object type repeatedly in a micro-benchmark, you get much better results than when creating a variety of objects in a real/complex application.
The problem with many object pool aproaches is that they a) require a key object, which costs as much or more than creating a simple object, b) involve some synchromization/locking which again can cost as much as creating an object c) require an extra object when adding to the cache (e.g. a Map.Entry), meaning your hit rate has to be much better for the cache to be worth while.
The most light weight, but dumb caching strategy I know is to use an array with a hashcode.
e.g.
private static final int N_POINTS = 10191; // or some large prime.
private static final Point[] POINTS = new Point[N_POINTS];
public static Point of(int x, int y, int z) {
int h = hash(x,y,z); // a simple hash function of x,y,z
int index = (h & 0x7fffffff) % N_POINTS;
Point p = POINTS[index];
if (p != null && p.x == x && p.y == y && p.z == z)
return p;
return POINTS[index] = new Point(x,y,z);
}
Note: the array is not thread safe, but since the Point is immutable, this doesn't matter. The cache works on a best effort basis, and is naturally limited in size with a very simple eviction strategy.
For testing purposes, you can add hit/miss counters to determine the caches effectiveness for you data set.
It sounds almost like a textbook example of the Flyweight pattern.
How many instances will share the same coordinates, how many will exist at the same time, and how many will be discarded?
Reusing the objects only has benefits if a significant percentage of live objects at one time are duplicates (at least 20%, I'd say) and overall memory usage is problematic. And if objects are discarded frequently, you have to construct the cache in a way that prevents it from becoming a memory leak (probably using soft/weak references).
Remember that caching these objects will influence concurrency and garbage collection in (most likely) a bad way. I wouldn't do it unless the other objects that refer to the points are long lived too.
As for most cases: it depends.
If your object is rather complex (takes a lot of time to instatiate) put can be expressed in a string, it makes sense to create and load them through a static factory method.
This also makes sense if some representations of the object are used more often than others (in your case maybe Point(0,0,0))
e.g
private static final HashMap<String, Point> hash = new HashMap<String, Point>();
public static Point createPoint(int x, int y, int z) {
String key = getKey(x,y,z);
Point created = hash.get(key)
if (created == null) {
created = new Point(x,y,z);
hash.put(key,created);
}
return created;
}
private static String createKey(int x, int y, int z) {
StringBuffer buffer = new StringBuffer();
buffer.append("x:");
buffer.append(x);
buffer.append("y:");
buffer.append(y);
buffer.append("z:");
buffer.append(z);
return buffer.toString()
}
Say you have the following class
public class AccessStatistics {
private final int noPages, noErrors;
public AccessStatistics(int noPages, int noErrors) {
this.noPages = noPages;
this.noErrors = noErrors;
}
public int getNoPages() { return noPages; }
public int getNoErrors() { return noErrors; }
}
and you execute the following code
private AtomicReference<AccessStatistics> stats =
new AtomicReference<AccessStatistics>(new AccessStatistics(0, 0));
public void incrementPageCount(boolean wasError) {
AccessStatistics prev, newValue;
do {
prev = stats.get();
int noPages = prev.getNoPages() + 1;
int noErrors = prev.getNoErrors;
if (wasError) {
noErrors++;
}
newValue = new AccessStatistics(noPages, noErrors);
} while (!stats.compareAndSet(prev, newValue));
}
In the last line while (!stats.compareAndSet(prev, newValue)) how does the compareAndSet method determine equality between prev and newValue? Is the AccessStatistics class required to implement an equals() method? If not, why? The javadoc states the following for AtomicReference.compareAndSet
Atomically sets the value to the given updated value if the current value == the expected value.
... but this assertion seems very general and the tutorials i've read on AtomicReference never suggest implementing an equals() for a class wrapped in an AtomicReference.
If classes wrapped in AtomicReference are required to implement equals() then for objects more complex than AccessStatistics I'm thinking it may be faster to synchronize methods that update the object and not use AtomicReference.
It compares the refrerences exactly as if you had used the == operator. That means that the references must be pointing to the same instance. Object.equals() is not used.
Actually, it does not compare prev and newValue!
Instead it compares the value stored within stats to prev and only when those are the same, it updates the value stored within stats to newValue. As said above it uses the equals operator (==) to do so. This means that anly when prev is pointing to the same object as is stored in stats will stats be updated.
It simply checks the object reference equality (aka ==), so if object reference held by AtomicReference had changed after you got the reference, it won't change the reference, so you'll have to start over.
Following are some of the source code of AtomicReference. AtomicReference refers to an object reference. This reference is a volatile member variable in the AtomicReference instance as below.
private volatile V value;
get() simply returns the latest value of the variable (as volatiles do in a "happens before" manner).
public final V get()
Following is the most important method of AtomicReference.
public final boolean compareAndSet(V expect, V update) {
return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
}
The compareAndSet(expect,update) method calls the compareAndSwapObject() method of the unsafe class of Java. This method call of unsafe invokes the native call, which invokes a single instruction to the processor. "expect" and "update" each reference an object.
If and only if the AtomicReference instance member variable "value" refers to the same object is referred to by "expect", "update" is assigned to this instance variable now, and "true" is returned. Or else, false is returned. The whole thing is done atomically. No other thread can intercept in between. As this is a single processor operation (magic of modern computer architecture), it's often faster than using a synchronized block. But remember that when multiple variables need to be updated atomically, AtomicReference won't help.
I would like to add a full fledged running code, which can be run in eclipse. It would clear many confusion. Here 22 users (MyTh threads) are trying to book 20 seats. Following is the code snippet followed by the full code.
Code snippet where 22 users are trying to book 20 seats.
for (int i = 0; i < 20; i++) {// 20 seats
seats.add(new AtomicReference<Integer>());
}
Thread[] ths = new Thread[22];// 22 users
for (int i = 0; i < ths.length; i++) {
ths[i] = new MyTh(seats, i);
ths[i].start();
}
Following is the github link for those who wants to see the running full code which is small and concise.
https://github.com/sankar4git/atomicReference/blob/master/Solution.java
I know Java doesn't have pointers, but I heard that Java programs can be created with pointers and that this can be done by the few who are experts in java. Is it true?
All objects in Java are references and you can use them like pointers.
abstract class Animal
{...
}
class Lion extends Animal
{...
}
class Tiger extends Animal
{
public Tiger() {...}
public void growl(){...}
}
Tiger first = null;
Tiger second = new Tiger();
Tiger third;
Dereferencing a null:
first.growl(); // ERROR, first is null.
third.growl(); // ERROR, third has not been initialized.
Aliasing Problem:
third = new Tiger();
first = third;
Losing Cells:
second = third; // Possible ERROR. The old value of second is lost.
You can make this safe by first assuring that there is no further need of the old value of second or assigning another pointer the value of second.
first = second;
second = third; //OK
Note that giving second a value in other ways (NULL, new...) is just as much a potential error and may result in losing the object that it points to.
The Java system will throw an exception (OutOfMemoryError) when you call new and the allocator cannot allocate the requested cell. This is very rare and usually results from run-away recursion.
Note that, from a language point of view, abandoning objects to the garbage collector are not errors at all. It is just something that the programmer needs to be aware of. The same variable can point to different objects at different times and old values will be reclaimed when no pointer references them. But if the logic of the program requires maintaining at least one reference to the object, It will cause an error.
Novices often make the following error.
Tiger tony = new Tiger();
tony = third; // Error, the new object allocated above is reclaimed.
What you probably meant to say was:
Tiger tony = null;
tony = third; // OK.
Improper Casting:
Lion leo = new Lion();
Tiger tony = (Tiger)leo; // Always illegal and caught by compiler.
Animal whatever = new Lion(); // Legal.
Tiger tony = (Tiger)whatever; // Illegal, just as in previous example.
Lion leo = (Lion)whatever; // Legal, object whatever really is a Lion.
Pointers in C:
void main() {
int* x; // Allocate the pointers x and y
int* y; // (but not the pointees)
x = malloc(sizeof(int)); // Allocate an int pointee,
// and set x to point to it
*x = 42; // Dereference x to store 42 in its pointee
*y = 13; // CRASH -- y does not have a pointee yet
y = x; // Pointer assignment sets y to point to x's pointee
*y = 13; // Dereference y to store 13 in its (shared) pointee
}
Pointers in Java:
class IntObj {
public int value;
}
public class Binky() {
public static void main(String[] args) {
IntObj x; // Allocate the pointers x and y
IntObj y; // (but not the IntObj pointees)
x = new IntObj(); // Allocate an IntObj pointee
// and set x to point to it
x.value = 42; // Dereference x to store 42 in its pointee
y.value = 13; // CRASH -- y does not have a pointee yet
y = x; // Pointer assignment sets y to point to x's pointee
y.value = 13; // Deference y to store 13 in its (shared) pointee
}
}
UPDATE: as suggested in the comments one must note that C has pointer arithmetic. However, we do not have that in Java.
As Java has no pointer data types, it is impossible to use pointers in Java. Even the few experts will not be able to use pointers in java.
See also the last point in: The Java Language Environment
Java does have pointers. Any time you create an object in Java, you're actually creating a pointer to the object; this pointer could then be set to a different object or to null, and the original object will still exist (pending garbage collection).
What you can't do in Java is pointer arithmetic. You can't dereference a specific memory address or increment a pointer.
If you really want to get low-level, the only way to do it is with the Java Native Interface; and even then, the low-level part has to be done in C or C++.
There are pointers in Java, but you cannot manipulate them the way that you can in C++ or C. When you pass an object, you are passing a pointer to that object, but not in the same sense as in C++. That object cannot be dereferenced. If you set its values using its native accessors, it will change because Java knows its memory location through the pointer. But the pointer is immutable. When you attempt to set the pointer to a new location, you instead end up with a new local object with the same name as the other. The original object is unchanged. Here is a brief program to demonstrate the difference.
import java.util.*;
import java.lang.*;
import java.io.*;
class Ideone {
public static void main(String[] args) throws java.lang.Exception {
System.out.println("Expected # = 0 1 2 2 1");
Cat c = new Cat();
c.setClaws(0);
System.out.println("Initial value is " + c.getClaws());
// prints 0 obviously
clawsAreOne(c);
System.out.println("Accessor changes value to " + c.getClaws());
// prints 1 because the value 'referenced' by the 'pointer' is changed using an accessor.
makeNewCat(c);
System.out.println("Final value is " + c.getClaws());
// prints 1 because the pointer is not changed to 'kitten'; that would be a reference pass.
}
public static void clawsAreOne(Cat kitty) {
kitty.setClaws(1);
}
public static void makeNewCat(Cat kitty) {
Cat kitten = new Cat();
kitten.setClaws(2);
kitty = kitten;
System.out.println("Value in makeNewCat scope of kitten " + kitten.getClaws());
//Prints 2. the value pointed to by 'kitten' is 2
System.out.println("Value in makeNewcat scope of kitty " + kitty.getClaws());
//Prints 2. The local copy is being used within the scope of this method.
}
}
class Cat {
private int claws;
public void setClaws(int i) {
claws = i;
}
public int getClaws() {
return claws;
}
}
This can be run at Ideone.com.
Java does not have pointers like C has, but it does allow you to create new objects on the heap which are "referenced" by variables. The lack of pointers is to stop Java programs from referencing memory locations illegally, and also enables Garbage Collection to be automatically carried out by the Java Virtual Machine.
You can use addresses and pointers using the Unsafe class. However as the name suggests, these methods are UNSAFE and generally a bad idea. Incorrect usage can result in your JVM randomly dying (actually the same problem get using pointers incorrectly in C/C++)
While you may be used to pointers and think you need them (because you don't know how to code any other way), you will find that you don't and you will be better off for it.
Technically, all Java objects are pointers. All primitive types are values though. There is no way to take manual control of those pointers. Java just internally uses pass-by-reference.
Not really, no.
Java doesn't have pointers. If you really wanted you could try to emulate them by building around something like reflection, but it would have all of the complexity of pointers with none of the benefits.
Java doesn't have pointers because it doesn't need them. What kind of answers were you hoping for from this question, i.e. deep down did you hope you could use them for something or was this just curiousity?
All objects in java are passed to functions by reference copy except primitives.
In effect, this means that you are sending a copy of the pointer to the original object rather than a copy of the object itself.
Please leave a comment if you want an example to understand this.
As others have said, the short answer is "No".
Sure, you could write JNI code that plays with Java pointers. Depending on what you're trying to accomplish, maybe that would get you somewhere and maybe it wouldn't.
You could always simulate pointes by creating an array and working with indexes into the array. Again, depending on what you're trying to accomplish, that might or might not be useful.
from the book named Decompiling Android by Godfrey Nolan
Security dictates that pointers aren’t
used in Java so hackers can’t break out of an application and into the operating
system. No pointers means that something else----in this case, the JVM----has to
take care of the allocating and freeing memory. Memory leaks should also
become a thing of the past, or so the theory goes. Some applications written in
C and C++ are notorious for leaking memory like a sieve because programmers
don’t pay attention to freeing up unwanted memory at the appropriate time----not
that anybody reading this would be guilty of such a sin. Garbage collection
should also make programmers more productive, with less time spent on
debugging memory problems.
Java reference types are not the same as C pointers as you can't have a pointer to a pointer in Java.
you can have pointers for literals as well. You have to implement them yourself. It is pretty basic for experts ;). Use an array of int/object/long/byte and voila you have the basics for implementing pointers. Now any int value can be a pointer to that array int[]. You can increment the pointer, you can decrement the pointer, you can multiply the pointer. You indeed have pointer arithmetics!
That's the only way to implements 1000 int attributes classes and have a generic method that applies to all attributes. You can also use a byte[] array instead of an int[]
However I do wish Java would let you pass literal values by reference. Something along the lines
//(* telling you it is a pointer)
public void myMethod(int* intValue);
You can, but not completely. You can't directly access pointers but you can have lists with variables that point to the same location. I came across a way by accident a few years ago.
I'm not sure why but in Java when you set a list to equal another list, rather than copying all the information, a pointer to the original list is made. I'm not sure if it applies to all forms of lists, but it has for the ones I have tested so far. I believe arrayList also has the function clone(), to circumvent this, if you wanted a proper seperate list.
int[] example
public class Main {
public static void main(String[] args){
int[] alpha = new int[] {1,2,3};
int[] beta = alpha;
beta[0]=9;
beta[1]=9;
beta[2]=9;
System.out.println("alpha: " + alpha[0] + ", " + alpha[1] + ", " + alpha[2]);
System.out.println("-beta: " + beta[0] + ", " + beta[1] + ", " + beta[2]);
}
}
arrayList example
import java.util.ArrayList;
public class Main {
public static void main(String[] args){
ArrayList<Integer> alpha = new ArrayList<>();
alpha.add(1);
alpha.add(2);
alpha.add(3);
ArrayList<Integer> beta = alpha;
beta.add(4);
beta.set(0, 5);
System.out.println("alpha: " + alpha.toString());
System.out.println("-beta: " + beta.toString());
}
}
All java objects are pointer because a variable which holds address is called pointer and object hold address.so object is pointer variable.
java can easily has pointer by knowing that the array name is pointer to the the first index. this why when we pass array to function we don't write its square brackets. because array is reference
public class Main
{
public static void func ( int ptr1[] , int ptr2[] )
{
int temp;
temp = ptr1[0];
ptr1[0] = ptr2[0];
ptr2[0] = temp;
}
public static void main(String[] args) {
int x = 5; int y = 8;
// in c language
// int *p = &x; int *q = &y;
// in Java
int p[] = new int[1];
int q[] = new int[1];
p[0] = x; // same as pointer
q[0] = y; // same as pointer
func( p , q ); // passing address ( refrence )
System.out.println( " After Swap " );
System.out.println( "x = " + p[0] + " " + "y = " + q[0] );
}
}