no pointer in Java => my problem

R

Roedy Green

1) in the real program I change 3 different objects of 3 different types in
my method and all I want to do is to return one of them and change in the
method the 2 others so that the changes are seen externally.
2) what is more, I want to learn how to do a thing like that in Java. In
C/C++ there's no problem with doing so,

But that is not idiomatic Java. You handle your problem by returning
an object. If you doggedly insisted on treating Java as if it were a
language with call by reference you would have to create a dummy
object with one reference in it. It could be an X[1] in a kludge.
Pass that to each method. The method then changes the reference in
the object and returns void.

See http://mindprod.com/jgloss/callbyvalue.html
http://mindprod.com/jgloss/callbyreference.html
 
R

Roedy Green

Then you have a very bad design. You need to fix the design, not try to
figure out how to get Java to support your bad design.

It is a C++ design that does not translate well. What you are doing
is asking how to translate "hot dog" into French, and insisting that
"chien chaud" is correct, even though that means literally in French
an overheated canine.

When translating between languages you have to use the idioms.
 
R

Roedy Green

What you need to do is learn to program, not hack. You seem to be
driven by ego, which is why you are getting responses about childhood
trauma. By the nature of your questions, your approaches to your
various problems are seriously flawed -- in any language.

This is pretty common any time anyone flips between languages. They
want to use the exact same idioms translated word for word into the
new language. The best way out of this is to find working examples of
code that do roughly what you want and modify them rather than writing
from scratch. That will tend you guide you into the natural flow of
Java. It has much more a channeling of the way to code that most
languages. This is partly why it is so popular with teams.
Everyone's code gets to look pretty much alike after a while.
 
R

Roedy Green

true. That's why I said "In short"... I generally think of objects as
references anyways, so I get confused when trying to explain.

This is a recurring topic. The consensus it pays to be nit picky in
language. If you are very rigid, people suddenly get it. Anything
you do to simplify, just confuses them. So we rigidly say, Java
always passes by value -- references and primitives. You can't pass
an object, only a reference to it.
 
P

Peter Kirk

What you are doing
is asking how to translate "hot dog" into French, and insisting that
"chien chaud" is correct, even though that means literally in French
an overheated canine.

And? What's a "hot dog" then? Don't tell me I've been cheated all these
years.....
 
A

antroy

rowla said:
1) in the real program I change 3 different objects of 3 different types in
my method and all I want to do is to return one of them and change in the
method the 2 others so that the changes are seen externally.

Returning one of the objects but changing 2 others is likely to play
hell with anyone else who has to maintain the code. Consider that they
want to know why reference B has been changed to point to a different
object, but the only reference that seems to be changed in the algorithm
is reference A. How are they to know where the reference is being
changed without digging unnecessarily deep?

Much better would to have 3 methods each returning the appropriate
object. That way it would be obvious where each reference was being
changed. Either that or if possible have the method return nothing, and
change the internal state of each object, which looking at your
simplistic example could be what you are actually trying to do.
 
B

Bryce (Work)

This is a recurring topic. The consensus it pays to be nit picky in
language. If you are very rigid, people suddenly get it. Anything
you do to simplify, just confuses them. So we rigidly say, Java
always passes by value -- references and primitives. You can't pass
an object, only a reference to it.

Point taken and agreed to.
 
?

=?ISO-8859-1?Q?Daniel_Sj=F6blom?=

Tim said:
rowla,

good question... the trick is to understand that in Java
private void f(Z j) {
does not equate to a C method of
private void f(Z *j) {
but rather more like another level of indirection
private void f(Z **j) {
j=&(new Z(65));
// or something like *(&j)=new Z(65); in the original.

This is false. It is actually very close to:

void f(Z *j)

Another layer of indirection would allow changing the value of the java
reference directly.
In short, this does not work in Java as a C progammer would expect.

IMO, it works exactly as any competent C programmer would expect it to work.
 
B

Bryan Castillo

Daniel Sjöblom said:
Your problem is not related to pointers.

void f(Z j) { j.i = 65; }

There are no value objects in java. Z is a reference passed by value.
References are similar to C pointers, except no pointer arithmetic (the
. operator dereferences, similar to -> in C). To simulate C style:

void f(struct Object **o) { *o = malloc(sizeof(struct Object)); }

you wrap your Object in a wrapper in java:

class Wrapper
{
Object o;
}

void f(Wrapper w) { w.o = new Object(); }

Java and C are both pass by value only. You can't change the value of a
passed pointer in a C function either (that is, it won't affect the
pointer from the view of the caller).

I have had a few people say this (C is only pass be value) because the
value
you are passing is an adress and you can't change the address. That
argument
doesn't make sense to me. Would you say only that C++ has something
other than pass by value? I think most C++ implementations will still
pass the value as an adrress when passing a reference, so in reality
you are still passing by value.
Ultimately you are probably just copying some 32bits into a register
and modifying that won't affect the caller. To affect the caller you
are modifying a value through another value, address, reference or
object (I don't see how there is really any difference, except the
language semantics). In c I could create a macro to make it like im
passing by reference.


#include <stdio.h>

#define pass_by_ref(A) _call_it(&(A))

void _call_it(int * a) {
*a = 0;
}

int main (void) {
int value;
value = 10;
printf("value = %d\n", value);
pass_by_ref(value);
printf("value = %d\n", value);
return 0;
}

Is that pass be reference then - so C does have pass by reference?

Why do people even argue about such a useless topic (pass by value or
pass by reference)? It shouldn't really matter.
 
L

Lasse Reichstein Nielsen

I have had a few people say this (C is only pass be value) because
the value you are passing is an adress and you can't change the
address. That argument doesn't make sense to me. Would you say
only that C++ has something other than pass by value?

Of C, C++ and Java, yes. There is a slight, semantic, difference
between passing a pointer to a value and passing a reference to a
variable. Sure you can implement the latter with the former, but
not the other way around. When passing a reference, you don't get
access to the pointer.
I think most C++ implementations will still pass the value as an
adrress when passing a reference, so in reality you are still
passing by value.

What the implementation does is not the point. It's probably machine
code anyway, where there are no pointers or references, just bit
patterns. The difference is what it looks like in the language. In C++
you can write

void foo(int &x) {
x++;
}
...
int y = 24;
foo(y);

Inside foo, x is just another variable. Outside foo, y is just another
variable. It is the way the paramter is passed that makes the difference.

Neither Java nor C have anything resembling this. C can pass pointers,
but then the pointer becomes the value. You need to explicitly
dereference it to affect the memory cell it is pointing to. Java
has nothing.

Notice that both C++ and Java have mutable structures that can be
passed as values and changed (C actually passes struct's as values).
That is not the same as a reference parameter.
(I don't see how there is really any difference, except the
language semantics).

That *is* the point. It makes a difference in what you can do, how
easy you can do it, and what the compiler can assume. You can do better
optimizations when you know that references to variables can't be
passed around. Java is designed to be safe, something you can never
be with first class pointers. Take this C program:
---
void foo() {
int i=42;
return &i;
}

void bar(int *p) {
int i;
printf("%d - %d\n",*p,i);
}

int main(int argc,char *argv[]) {
bar(foo());
}
---
Is that pass be reference then - so C does have pass by reference?

No, that is an encoding that works like it. You can also encode objects
in C, but that doesn't make it object oriented.
Why do people even argue about such a useless topic (pass by value or
pass by reference)? It shouldn't really matter.

Well, I *am* a language theroretician, so I guess because it's fun :)
/L
 
?

=?ISO-8859-1?Q?Daniel_Sj=F6blom?=

Bryan said:
I have had a few people say this (C is only pass be value) because the
value
you are passing is an adress and you can't change the address. That
argument
doesn't make sense to me. Would you say only that C++ has something
other than pass by value?

Of the three languages under discussion, yes.
I think most C++ implementations will still
pass the value as an adrress when passing a reference, so in reality
you are still passing by value.

No. Mainly because we are *not* writing assembly. We are writing in a
high level language and need to know how something behaves in *this
language*.
Ultimately you are probably just copying some 32bits into a register
and modifying that won't affect the caller. To affect the caller you
are modifying a value through another value, address, reference or
object (I don't see how there is really any difference, except the
language semantics).

Which is the point. Language semantics. Different languages behave
differently.
In c I could create a macro to make it like im
passing by reference.


#include <stdio.h>

#define pass_by_ref(A) _call_it(&(A))

void _call_it(int * a) {
*a = 0;
}

int main (void) {
int value;
value = 10;
printf("value = %d\n", value);
pass_by_ref(value);
printf("value = %d\n", value);
return 0;
}

Is that pass be reference then - so C does have pass by reference?

No it is pass by value. Just obfuscated by the macro.
Why do people even argue about such a useless topic (pass by value or
pass by reference)? It shouldn't really matter.

Well, it is not something that keeps me up all night thinking about it
either. But of course it makes a difference when you are writing
something in a language. Pass by value is IMO more intuitive and makes
for easier to predict/understand code. For example, 90% of the time you
see pass by reference in C++ it is passed as a const reference, because
changing the value of something passed by reference is still a bad idea.
 
B

Bryan Castillo

Lasse Reichstein Nielsen said:
I have had a few people say this (C is only pass be value) because
the value you are passing is an adress and you can't change the
address. That argument doesn't make sense to me. Would you say
only that C++ has something other than pass by value?

Of C, C++ and Java, yes. There is a slight, semantic, difference
between passing a pointer to a value and passing a reference to a
variable. Sure you can implement the latter with the former, but
not the other way around. When passing a reference, you don't get
access to the pointer.
I think most C++ implementations will still pass the value as an
adrress when passing a reference, so in reality you are still
passing by value.

What the implementation does is not the point. It's probably machine
code anyway, where there are no pointers or references, just bit
patterns. The difference is what it looks like in the language. In C++
you can write

void foo(int &x) {
x++;
}
...
int y = 24;
foo(y);

Inside foo, x is just another variable. Outside foo, y is just another
variable. It is the way the paramter is passed that makes the difference.

Neither Java nor C have anything resembling this. C can pass pointers,
but then the pointer becomes the value. You need to explicitly
dereference it to affect the memory cell it is pointing to. Java
has nothing.

Notice that both C++ and Java have mutable structures that can be
passed as values and changed (C actually passes struct's as values).
That is not the same as a reference parameter.
(I don't see how there is really any difference, except the
language semantics).

That *is* the point. It makes a difference in what you can do, how
easy you can do it, and what the compiler can assume. You can do better
optimizations when you know that references to variables can't be
passed around. Java is designed to be safe, something you can never
be with first class pointers. Take this C program:
---
void foo() {
int i=42;
return &i;
}

void bar(int *p) {
int i;
printf("%d - %d\n",*p,i);
}

int main(int argc,char *argv[]) {
bar(foo());
}
---
Is that pass be reference then - so C does have pass by reference?

No, that is an encoding that works like it. You can also encode objects
in C, but that doesn't make it object oriented.

It doesn't? Sure the language may not be object oriented, however I
can design applications using objects and still implement them in C.
I have done this many times using structs containing pointers to
functions, so the functions used to implement the behavior of the
objects can be changed.

I guess you, being a language theroretician, would care how the
language supports the design and I care about it in terms of
maintaining applications over time, however the design of the
application always matters to me more.

Regarding the concepts of addresses, references and pointers, I see it
as only 2 options. 1 - there are ways to pass things around to other
control constructs (functions, objects, whatever...) where the thing
is logically changed to the creator or originator of the thing. 2 -
there are ways to pass things around to other control structures
where the changes to the thing are not seen by the orginator.

To me, passing by address or reference usually falls under case 1
while passing by value falls under case 2.

In java, passing around objects which may be modified falls under case
1 and primitive types fall under case 2. You might go farther and
start talking about objects returned through RMI or SOAP (RPC) and
start classifying those objects as being modifiable and visible to
another scope or not.

It just seems to me that describing parameters to methods as being
passed by reference, address or value, does not accurately describe or
address the issues you face while designing applications.
 
R

Roedy Green

Would you say only that C++ has something
other than pass by value?

C++ offers the possibility of creating an object on the stack as a
parameter, or passing the address of an object as a parameter.

Ada offers the possibility of passing the address of the object, or
the address of a reference to the object (perhaps more).

Java just offers passing the address of an object as a parameter.

This results in greater simplicity with not much loss in
functionality. The C++ folk wanted to be able to do everything you
could do in assembler in a reasonably platform-independent way. The
Java folk were trying to design a simplified language for a TV set top
box.

Call by reference is an Algol-60ish sort of notion. We later
discovered that it just confuses the heck out of people when methods
can implicitly change the values of local variables in their callers.

Part of the key to writing maintainable code is to reduce sneaky side
effects.
 
R

Roedy Green

Sure the language may not be object oriented, however I
can design applications using objects and still implement them in C.

Consider that Bjarne Stroustrup's first C++ compiler generated C code.
So obviously you can do OO in C, it is just a lot uglier.
 
S

Sudsy

Roedy Green wrote:
Consider that Bjarne Stroustrup's first C++ compiler generated C code.
So obviously you can do OO in C, it is just a lot uglier.

But it's an important point. Part of my disdain for C++ stemmed from
the fact that it was just a "veneer" applied on top of standard C. It
couldn't force you to use object-oriented paradigms. As such, and as
reported by research organizations like Forrester, much if not most
of so-called C++ code is actually procedural C.
What I found attractive about Java was that it DID force you to use
object-orientation. No back-sliding into convenient but trouble-prone
constructs. No more worries about malloc() calls without matching
free()s. A powerful framework which added workhorse classes over the
years.
I get annoyed when people complain that Java (or any language in fact)
doesn't support the same programming paradigm as another language.
Get over it!
Use the right tools for the job and learn how to use your tools
effectively.
Ever try to turn a Philip's head screw with a chisel? SWIM?
 
D

Dale King

Chris Smith said:
Dale's right, but http://jinx.swiki.net/66 might at least point in the
right direction for finding a solution.

I've got a partially written article that goes into much more depth than
that article providing a large list of alternative design strategies and
reasoning behind them. One of these days I need to get that in a publishable
state and post it on jinx.
 
D

Dale King

rowla said:
I'm not saying that C++ is better than Java, but I found pointers very
useful (goto are not good of course:)

And the rest of the world has found that pointers such as in C/C++ are the
source of many errors and confusion in programs. Errors like dangling
pointers, unfreed memory, and overwriting buffers that are pointed to by
pointers are common. There is a lot of confusion in C++ when you have to
start talking about the difference between value semantics for objects and
reference semantics for objects. That is why they were eliminated in Java.
There is value in indirection but not the wild anarchy of pointers pointing
to whatever they want. In Java you only have indirection by pointing to
objects. Java only has reference semantics for objects and no value
semantics. That is why we say that objects are never passed to a method only
references and those are passed by value.
 
D

Dale King

Bryan Castillo said:
Daniel Sjöblom <[email protected]_NOSPAM> wrote in message

I have had a few people say this (C is only pass be value) because the
value
you are passing is an adress and you can't change the address. That
argument
doesn't make sense to me. Would you say only that C++ has something
other than pass by value? I think most C++ implementations will still
pass the value as an adrress when passing a reference, so in reality
you are still passing by value.

Here is an explanation I prepared a long while back on this subject and I
guess its about time to repost it:

Question:
Does Java pass objects by reference or by value?

Answer:
Since it makes no sense to begin any argument without agreed upon
definitions let's formally define our terms. I will use abstract
pseudocode to keep the issue from being clouded by the idiom of a
particular language. The source of my information is the book
"Advanced Programming Language Design" by Raphael A. Finkel.

For those unfamiliar with the term below an L-value is an expression
that can appear on the left side of an assignment statement. It is
basically a way to address where a variable is stored. Variables
and other ways to refer to locations in memory are L-values. Most
expressions are not L-values, e.g. ( x * 2 )

We assume the presence of a procedure named f that takes a formal
parameter s. We call that function giving it an actual parameter g.

The calling code:
f( g )

The function:
procedure f( s )
begin
-- body of the procedure
end;

There are several parameter passing semantics that have been
proposed or used:

value
The value of the actual parameter is copied into the formal
parameter when the procedure is invoked. Any modification of
the formal parameter affects only the formal parameter and
not the actual parameter. This is the most common form of
parameter passing and is the only one provided in C and Java.

result
The value of the formal parameter is copied into the actual
parameter when the procedure returns. Modifications to the
formal parameter do not affect the formal parameter until the
function returns. The actual parameter must be an L-value. It
is usually invalid to pass the same L-value to more than one
result parameter, but the compiler cannot always detect this.
The best example of this is out parameters in CORBA.

value result
Combination of value and result semantics. The best example of
this are inout parameters in CORBA.

reference
The L-value of the formal parameter is set to the L-value of the
actual parameter. In other words, the address of the formal
parameter is the same as the address of the actual parameter. Any
modifications to the formal parameter also immediately affect the
actual parameter. FORTRAN only has reference mode (expressions are
evaluated and stored in a temporary location in order to obtain an
L-value). C++ has reference parameters by putting a & before the
formal parameter name in the function header. Reference mode can
be simulated in C using pointers and adding the & to the actual
parameter and dereferencing the formal parameter within the
function.

readonly
Can use either value or reference mode, but modification of the
formal parameter is forbidden by the compiler.

macro
name
These two have been used in the past, but are very much out of favor
because they are confusing and difficult to implement. Therefore I
won't bother trying to explain them.

Now that we have some definitions of terms we can return to the question.
Does Java pass objects by reference or by value?

The answer is NO! The fact is that Java has no facility whatsoever to
pass an object to any function! The reason is that Java has no variables
that contain objects.

The reason there is so much confusion is people tend to blur the
distinction between an object reference variable and an object instance.
All object instances in Java are allocated on the heap and can only be
accessed through object references. So if I have the following:

StringBuffer g = new StringBuffer( "Hello" );

The variable g does not contain the string "Hello", it contains a
reference (or pointer) to an object instance that contains the string
"hello".

So if I then call f( g ), f is free to modify its formal parameter s to
make it point to another StringBuffer or to set it to null. The function
f could also modify the StringBuffer by appending " World" for instance.
While this changes the value of that StringBuffer, the value of that
StringBuffer is NOT the value of the actual parameter g.

Imagine for instance if I set g to null before passing it to f. There is
no StringBuffer now to modify and f can in no way change the value of g
to be non-null.

A real world analogy would be if I had a piece of paper with an address
on it and I copied that address onto another piece of paper that I gave
you. That piece of paper is not the house at that address it is only
a reference to that house. There could of course be several pieces of
paper with that address on it. You could then go to that house and
modify it by painting it blue, but that does not change the piece of
paper I gave you. You could change the address on your paper, but that
does not change the address on my paper. You cannot change my paper,
since we assume that you don't even know where my paper is or really
even the existance of my paper. That is pass by value. I gave you the
value of my paper.

It's a bit harder to come up with a good real world analogy for pass by
reference. If I gave you my piece of paper which you hand back to me when
you are done (possibly changing the address), that would be like value
result mode. Result mode would be me handing you a blank piece of paper
on which you write the address and return to me.

The bottom line is Java only has variables that hold primitives or object
references. Both are passed by value.
 
T

Timo Kinnunen

A real world analogy would be if I had a piece of paper with an address
on it and I copied that address onto another piece of paper that I gave
you. That piece of paper is not the house at that address it is only
a reference to that house. There could of course be several pieces of
paper with that address on it. You could then go to that house and
modify it by painting it blue, but that does not change the piece of
paper I gave you. You could change the address on your paper, but that
does not change the address on my paper. You cannot change my paper,
since we assume that you don't even know where my paper is or really
even the existance of my paper. That is pass by value. I gave you the
value of my paper.

It's a bit harder to come up with a good real world analogy for pass by
reference.

Please, let me help:

A real world analogy would be if I had a piece of paper with an address
of a house on it and someone copied that address onto another piece of
paper that you received. That piece of paper is not the house at that
address it is only an lvalue to that house. There could of course be
several pieces of paper with that address on it. You could then go to
that house and modify it by painting it blue, but that does not change
the piece of paper you received. If the address isn't written in ink, you
could change the address on your paper, but that does not change the
address on my paper. You cannot change my paper, since we assume that you
don't even know where my paper is or really even the existance of my
paper. That is pass by reference. You received the lvalue on my paper.

Sorry, I couldn't resist :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,071
Latest member
MetabolicSolutionsKeto

Latest Threads

Top