Skip to main content
GameDev.net gamedev.net
🔒 Locked

Java pointer or similar

Started by user0 Jun 19, 2010 at 11:20 PM 41 replies 7.2k views
Original Post
user0
user0
Im trying to make some of my c++ functions in java I didnt think it would be very hard but now I am wondering how to do certain things without pointers. Alot of my functions work like that I have one that is used to get a web page and takes a pointer for the header and body to be stored in 2 different variables. I cannot do that in java and the only way I can think of would be make all of these into classes and that seems to be a overkill for each little thing.

Another thing that has me concerned is wouldnt passing by value be so much slower than just passing a pointer for certain things?

Is there a way I could make this work?
        public static void changestring(String hold){            hold = "jeff";        }	public static void main(String[] args) {		String hold = new String("ffej");                System.out.println(hold);                changestring(hold);                System.out.println(hold);	}
Zahlman
Zahlman
Java does pass by value. Always. That just doesn't have the effect that you expect it to.

Java variables of object types do not actually hold the underlying objects directly. They hold a sort of handle that automatically accesses the underlying object through its interface. That is, Java passes a thing that already is a reference, by value.

This is all explained in more painstaking detail here.

The interface for java.lang.String does not allow for any kind of change to the string data. Ever. You can create new strings, of course.

When you assign 'hold = "jeff"', you actually cause the handle held by the variable 'hold' to stop referring to what it used to, and start referring to the string "jeff". At the end of the function, the variable doesn't exist any more, so nothing has really been affected.

You can perform the necessary indirection by making a class that holds a string, or by passing a 1-element array and assigning the array contents. However, both of these solutions are fairly ugly. You could also use an existing class such as StringBuffer or StringBuilder which do allow changes to the underlying object through their interface. But in most cases, you don't really want to "pass by reference" in Java. Communicate information out of the function in the natural way: by returning a value. If necessary, have the caller assign the returned value back over the passed-in variable.

Keep in mind: what if you ever want to call the function with a temporary, calculated value? How would you examine the modifications in that case?
user0
user0
Well after much searching and the help from Zahlman I have figured out a way o do what I need with objects like Zahlmans suggested StringBuffer.

For temporary calculated values it depends on the scenario but if I need something like that I could make an overloaded function to handle it.

Why would I not want to use pass by reference wouldnt be alot slower to bass everything by value like lets say i have a 5meg sound file in memory passing that by value would mean coping it but by reference i could work on the original and not have to return the whole thing either.


I think I just didnt understand how the whole pass by reference works.

class StringObj {
public String value;
}

public class Program {

static void changestring(StringObj hold){
hold.value = "jeff";
}


public static void main(String[] args) {
StringObj hold = new StringObj();
hold.value = "ffej";
System.out.println(hold.value);
changestring(hold);
System.out.println(hold.value);
}

}
way2lazy2care
way2lazy2care
Quote:
Original post by jeff8j
Im trying to make some of my c++ functions in java I didnt think it would be very hard but now I am wondering how to do certain things without pointers. Alot of my functions work like that I have one that is used to get a web page and takes a pointer for the header and body to be stored in 2 different variables. I cannot do that in java and the only way I can think of would be make all of these into classes and that seems to be a overkill for each little thing.


C# WINS AGAIN!
haegarr
haegarr
Quote:
Original post by jeff8j
Why would I not want to use pass by reference wouldnt be alot slower to bass everything by value like lets say i have a 5meg sound file in memory passing that by value would mean coping it but by reference i could work on the original and not have to return the whole thing either.
This would be true if the 5meg buffer would be the value, but it isn't (usually). In fact, the buffer is referenced by a handle, and the handle is copied! So you have 2 different handles that both refer to the same buffer.

What Java does for non primitives is like copies of pointers:
Object * a = new Object;
Object * b = a;
so you have 2 pointers a and b where b is made by copy, hence both variables refers to the same object. But both variables are still independend: Changing the one doesn't change the other. I.e.
b = 0;
doesn't change variable a (or the object). Conclusion: Not the object is copied but the pointer is!

See e.g. the sections "call by value", "call by reference", and especially "call by sharing" in this wikipedia article.
XTAL256
XTAL256
I used to not understand it either (and i still don't fully understand it).
But the thing to realise is that a "pointer" is just an integer number that holds the memory location of an object.
So Java passes everything by value, but for objects that "value" is the memory location. So it's actually passing a pointer to the object.

That's why, as others have mentioned, you can't change what a function parameter points to, but you can definitely pass a pointer to an object.
[Window Detective] - Windows UI spy utility for programmers
vertexbuff3r
vertexbuff3r
Quote:
Java does pass by value. Always.
Java pass nothing but primitive data types by value. Everything else, is object in java and is passed *always* by reference (aka pointer) for efficiency.

You are right in your explanation further on Zahlman, but you are complicating too much. Put it simply like this:

Javas "reference" is what pointer in c/c++ is.

You should just never worry about that in Java, that is the point why java creators removed pointers in sense as you know of them from C/C++. You can always work as if you have value passed object, and let java manage pointer datails for you.

By the way it is possible to pass pointers from C/C++ further on in Java and to use them; in some special (homemade) ways of course.

LWJGL use to do that (I haven't used it for years now), and some real time java implementations use to do that as well. If you really miss pointers and structures, you can read you structs and buffers into javas byte array and treat it as "memory" and do pointer arithmetic on that buffer in terms of indices, but I really se no point of doing it :-).

You don't need C/C++ to read a file into java; you can read any file very efficiently with Java's IO.

Otherwise if you really want Java to be C like, read in your string into char array :-).

You also seem to think in term of char* from C (not ever string class from c++), becuase what you are illustrating is probably what one would write in C. Below are two ways how you can code your example. Observe that the "char array way" I am doing is painfull in long term, one doesn't do things that way in Java. Use StringBuffer instead, which is mutable string class in java.

class st {    static void change(char[] s){	for( int i=0, l = s.length-1; i<s.length / 2; i++, l--){	    char c = s;	    s = s[l];	    s[l] = c;	}    }    public static void main(String[] a){	StringBuffer s = new StringBuffer("ffej");	System.out.println("Original buffer: "+s);	for( int i=0, l = s.length()-1; i<s.length() / 2; i++, l--){	    char c = s.charAt(i);	    s.setCharAt(i,s.charAt(l));	    s.setCharAt(l,c);	}	System.out.println("Reversed: "+s);	System.out.println(" ... or  you could use builtin \"reverse()\" call :-)");	s.reverse();	System.out.println("Reversed again: "+s);			System.out.println("Now C way: ");	char[] ch = s.toString().toCharArray();	System.out.print("Char array: ");	System.out.println(ch);	change(ch);	System.out.print("Reversed char array: ");	System.out.print(ch);    }}


Without trying to be rude, may I suggest that you read some good intor book about Java & OO? At least google for StringBuffer, and also for JNI if you want to learn more about interaciton between Java and C/C++.
GeirGrusom
GeirGrusom
Just wanted to annoy and state that Java objects are not exactly the same as C++ pointers :) since Java objects' pointer value can vary as the GC moves objects around.
In C# you have the fixed statement to keep the object from being moved by the GC which in turns enables you to edit the contents of a string in a very ugly manner.

string my_Str = "abc123";fixed(char* ptr = my_str){  ptr[0] = ':';  ptr[1] = 'D';}


It is ugly for two reasons: pointers (unsafe), and the fact that .NET and Java string characters does not necessarily take one 16-bit char, they may in rare cases take two, in which such editing may in fact make the string invalid.

So: you can't, or at least shouldn't edit strings by removing or editing individual charcaters. Use string searcing an replacement functions that exists in Java instead. StringBuilder should be used to build large strings to keep short-lived string objects to a minimum, which I believe is it's original intent.

If you want to edit a string in a function, return the result rather than editing an input value.
vertexbuff3r
vertexbuff3r
Quote:
Just wanted to annoy and state that Java objects are not exactly the same as C++ pointers :)


Ofcourse they are not :-); references to objects are "pointers-alike", but object itself is not same as its reference. Reference to an object and object itself are two different things.

StringBuilder is good alternative to StringBuffer, albeit not thread safe. It offers better performance on cost of thread safety.
arbitus
arbitus
Quote:
Original post by vertexbuff3r
Quote:
Java does pass by value. Always.
Java pass nothing but primitive data types by value. Everything else, is object in java and is passed *always* by reference (aka pointer) for efficiency.


This statement is incorrect, but I think you are simply confusing the naming convention of the concept. Java is always "pass by value," it has no ability to pass by reference. When you pass a reference to a method, you always pass the reference by value, meaning you get a copy of the reference. Take the following:

public class Foo {	public int Bar;}public class Test {	public static void main(String[] args) {		// TODO Auto-generated method stub		Foo foo = new Foo();		foo.Bar = 5;				fooTest(foo);				System.out.println(foo.Bar);	}		public static void fooTest(Foo foo) {		foo = new Foo();		foo.Bar = 10;	}}


What will be printed? 5 of course...

This is because Java passes references by value. The method receives a copy of the reference, so that when it reassigns the reference to a new object, this is not visible outside of the method scope. If Java were to pass by reference, meaning it passes "the actual reference itself," then the method would print 10.

This is why Java cannot implement a simple swap method.

C++ and C# allow for pass by reference, using the "&" symbol and "ref" keyword respectively. If you check the usage of these items, you will see why "pass by reference" is a very different creature than what Java allows.

And, if you don't believe me, ask this guy.
Sneftel
Sneftel
Quote:
Original post by vertexbuff3r
Java pass nothing but primitive data types by value. Everything else, is object in java and is passed *always* by reference (aka pointer) for efficiency.

Keep in mind the important difference between "passing by reference" and "passing a reference". The acid test for call-by-reference versus call-by-value is the swap test. That is, can you implement swap() as a function?
void swap(Object a, Object b) {  Object t = a;  a = b;  b = t;}

In a language which uses call-by-reference (such as Perl, or C++ when explicitly told to pass by reference), the result of this function will be visible from the calling code. In a language which uses call-by-value (most languages, including Java) the function will have no lasting effect once it returns.

Incidentally, it is also impossible for Java to be call-by-reference because code like the above would invalidate the typing derivations.
KB9AGT is Douglas
KB9AGT is Douglas
When you say pointer, we assume you mean reference. Therefore you do need to create an object or a class as you stated. Not too hard.

class Letter {  char c;}public class PassObject {  static void passLetter(Letter y) {    y.c = 'z';  }  public static void main(String[] args) {  Letter x = new Letter();  x.c = 'a';  System.out.println("1: x.c: " + x.c);  passLetter(x);  System.out.println("2: x.c: " + x.c);  }} ///:~


Try some object methods on Object which are built in to java.lang.
"Everything is an object."

[Edited by - KB9AGT is Douglas on June 23, 2010 5:16:34 PM]
vertexbuff3r
vertexbuff3r
Quote:
This statement is incorrect, but I think you are simply confusing the naming convention of the concept. Java is always "pass by value," it has no ability to pass by reference.
No, I am not, but you are confusing what I was talking about. Java never passes OBJECTS by value, ALWAYS by reference. What you are confusing here is how objects vs. addresses to objects are passed.
Quote:
When you pass a reference to a method, you always pass the reference by value, meaning you get a copy of the reference. ...
You are 100% correct about how references are passed, but it is not what I was talking about. :) I talked about how OBJECTS are passed :-) in order to simplify correct but complicated explanation from Zahlman.

If objects were passed by values, it would mean that you have to copy possibly kilobytes of data everytime a function is called. That would be extremely inneficient. Instead references are passed around (yes by copying them :-).

When you declare a function say your testFoo(Foo foo) or swap(Object o1, Object o2), anything you declare in parenthesis is just local variable(s), and as such they live on stack of your method. Difference between those declared in parenthesis and those declared in braces (in function body) is that compiler will initiate variables in parenthesis from outside (at call time).

Maybe there is some confusion because of C++'s concept of references. In java you don't have to guarantee that reffered object is valid as you have for C++ reference. In C++ you can not have null reference; by declaring a reference you always guarantee that it points to a valid object. C++ refs are a way for you to guarantee certain things to compiler, so it can do some optimizations. If you remove that restriction in c++, nothing but syntatic sugar would left. Java references are NOT as c++ references; java references are more like c++ pointers.

One should not carry over literall knowledge of one language to another. Just because a thing is called "a reference" in java, does not mean it is same as reference in another language nor in some universall "programming" knowledge as that article wants it. Obviously pass by reference in Java is defined different than what Stanchfield likes it to be :-).

Frankly, to me it seems that Stanchfield is out for language fascism. Point of his article seems to be some kind of "sun made language misstake" :-). In Java, term passed-by-reference means 110% of times, how OBJECTS are passed, at implementation level; not reference to object itself, and that is what Stancfield opposes to.

He is correct about java references being more like C pointers and Sun wanted to make difference; but than, it is nothing new; that is something I learned like 12 years ago at first Java course at university. Also fact that references are copyed over was something we learned too, at very beginning, so his article is kind-of nothing new to hear. I didn't even thaught that somebody could start argue about such basic fact of Java language.

Maybe Stanchfield and anybody who agrees with his pointless article would like to create a third java-only-reference-call and get Sun (or Oracle) to make it standard jargon so we can all speak same language and be happy :-).

Also not to be rude, but when talking about java there is some parlance that everybody speaks. Otherwise just learn how references works in java: references to objects are primitives types and are copying over, while ojects itself are never copyed. Talking about passing by reference is about passing objects in java, not references itself, no matter how much some obscure article writer disslikes it.

usch ... let me citate myself:
Quote:
Javas "reference" is what pointer in c/c++ is.
Exactly what Stancfield come to conclusion too :-).

[Edited by - vertexbuff3r on June 23, 2010 6:47:21 PM]
Antheus
Antheus
Quote:
Original post by vertexbuff3r
Quote:
This statement is incorrect, but I think you are simply confusing the naming convention of the concept. Java is always "pass by value," it has no ability to pass by reference.
No, I am not, but you are confusing what I was talking about. Java never passes OBJECTS by value, ALWAYS by reference. What you are confusing here is how objects vs. addresses to objects are passed.

Yay for pointless semantic wars.

Java passes references to instances by value (how's that for clarity).

In Java, an instance cannot have its value taken, it may only be referenced. The concept of by-value simply doesn't exist. References are first class members, and they are passed by value.

If instances were passed by reference, they would mean in C-ish terms:
void foo(Bar * &b); // pointer to instance of Bar passed by reference



Long story short - swap() cannot be implemented in Java as it is in C or C++ or any of those languages.
shultays
shultays
java always pass by value, it sends a copy of the reference object which refers to actual object.

like in c++

void test(Object *b){
...
}

Object *a = new Object();
test(a);

in this case it sends a copy of the pointer a to test function. this is same in java, just you don't put * before references but again it sends a copy of a pointer (reference) to test function and if test sets b to something it does not affect a.
taytay
vertexbuff3r
vertexbuff3r
Quote:
Java passes references to instances by value (how's that for clarity).
Very bad, since reference is always a reference to an instance (or special instance null), so you simply could have hade said that references are passed by value :-).

Yes references are primitive types, I guess what you mean with first class members?
Quote:
The concept of by-value simply doesn't exist. References are first class members, and they are passed by value.
How's that for XOR-ing yourself here? :-) I guess you mean concept of passing objects by value does not exist? References to objects are passed around, and those references are passed by value. I hope you mean that :-).

Quote:
In Java, an instance cannot have its value taken
What would it mean to get "its value taken"?

Quote:
If instances were passed by reference, they would mean in C-ish terms:
void foo(Bar * &b); // pointer to instance of Bar passed by reference
:-) No it wouldn't :-)

In C it would mean syntax error. If you want to pass by reference in C you write foo(Bar **b)

In C++ it would mean what you say; but Java reference is not pointer to a reference; it is simply reference, so you would use foo(Bar &b).

Yet java objects are passed by passing javas object references around; those semantics are not same as semantics of C++ references, so comparing to C++ is not valid. Otherwise everything beside that is correct, and already said :-).
arbitus
arbitus
Quote:
No, I am not, but you are confusing what I was talking about. Java never passes OBJECTS by value, ALWAYS by reference. What you are confusing here is how objects vs. addresses to objects are passed.


No, I absolutely know what you are talking about and you are completely incorrect. The phrase "pass by value" and "pass by reference" have very specific meanings, and you are using them incorrectly. Additionally, you do not "pass OBJECTS" in Java, you pass references to objects.

The problem with declaring this as a semantics issue is that you are using the terms absolutely incorrectly. It is like suddenly declaring that the word DOG is a reference to a Cat object. In addition, most of the rest of your post is either wrong or misguided, yet you speak to me (a professional Java developer for many years) as if I have no idea what I am talking about.
vertexbuff3r
vertexbuff3r
Quote:
The phrase "pass by value" and "pass by reference" have very specific meanings,
Yes they have; but pass by reference also have somewhat special and different meaning in Java, than in your parlance.

Quote:
Additionally, you do not "pass OBJECTS" in Java, you pass references to objects.
Yes, and what I was telling all the time if not that? Passing "by value" would obviusly mean passing object on the stack which never happeneds in Java.

Quote:
The problem with declaring this as a semantics issue is that you are using the terms absolutely incorrectly.
I didn't declared anything; you picked up on language detail while ignoring rest :-)

You don't happen to have second name Stenchfield? =) Obviously, since evrything I said and wrote is nonsense in your eyes, read about source of your confusion elsewhere:

http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html

Quote:
In addition, most of the rest of your post is either wrong or misguided
Enlighten me :-) ... I guess my socks are also stinking and I am an ugly jerk who should be shut at least twice with a shotgun? :-)

Quote:
yet you speak to me (a professional Java developer for many years) as if I have no idea what I am talking about.
Ouch, that must be the biggest reason why I am wrong :-).

No my friend, I don't; I clearly said that you have right in what you described, albeit you missunderstand what I talked about. Might be too fast or incomplete reading, but try againg to read my posts carefully, maybe wihout arrogance this time?

Obviously we are meaning pretty much same thing however I do use relaxed terminology as I am used to from 12 years of Java programming. Maybe we can agree on this:

Quote:
Most people at Sun in particular have actually said that Java is 'pass-by-reference-by-value' - because the memory state of the object itself isn't copied (which is true pass by value of a heap element), but that the reference is copied.
(by anonymous).
arbitus
arbitus
Quote:
Yes they have; but pass by reference also have somewhat special and different meaning in Java, than in your parlance.


No, they do not. There is no such thing as pass by reference in Java. The only people who claim that there is are people who heard of the concept from C++ and assumed it applied to Java references. These people are mistaken and ill informed.

Quote:
Yes, and what I was telling all the time if not that? Passing "by value" would obviusly mean passing object on the stack which never happeneds in Java.


That is absolutely not what "pass by value" means. Again, you are ill informed.

I apologize if I am sounding combative, but at this point, you are spreading misinformation in a beginners forum.

Quote:

You don't happen to have second name Stenchfield? =) Obviously, since evrything I said and wrote is nonsense in your eyes, read about source of your confusion elsewhere:

http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html


Wow, this link reiterates exactly what I have said, and you seemed to have somehow missed that. It explicitly states that Java has no "pass by reference" and that the phrase is inappropriately uttered.

Quote:
Most people at Sun in particular have actually said that Java is 'pass-by-reference-by-value' - because the memory state of the object itself isn't copied (which is true pass by value of a heap element), but that the reference is copied.
(by anonymous).[/quote]

Yes, pass-by-reference-by-value is a completely different concept than "pass by reference," yet you still insist that it is, even when Java sources and Sun itselfs says that you are wrong. "Pass by reference" has a very, very specific meaning and you are misusing it. You are not simply playing "fast and loose" with the jargon, you are completely incorrect.
shultays
shultays
Link from Sun Web Site

"Reference data type parameters, such as objects, are also passed into methods by value. This means that when the method returns, the passed-in reference still references the same object as before. However, the values of the object's fields can be changed in the method, if they have the proper access level."

taytay

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.