who can tell me why

W

weironghai

class Test{
public static void main(String args[]){
String a = new String( "2" ), b;
b = a;
a = "3";
System.out.println( b );

String c[]= { "1","2","3" }, d[];
d = c;
c[0] = "4";
System.out.println( d[0] );
}
}

in my opinion ,i thought it will print
3
4
but in fact ,it printed
2
4


who can tell me why?
 
A

Adam Warner

class Test{
public static void main(String args[]){
String a = new String( "2" ), b;
b = a;
a = "3";
System.out.println( b );

String c[]= { "1","2","3" }, d[];
d = c;
c[0] = "4";
System.out.println( d[0] );
}
}

in my opinion ,i thought it will print
3
4
but in fact ,it printed
2
4


who can tell me why?

Java is strictly pass by value and assignment by value. You do need to
appreciate the difference between passing and assigning a primitive value
and passing and assigning a reference value. Reference values are pointers
to objects and objects may be mutated.

In outcome 1, a is a pointer to (the reference value of) String object "2".
b is assigned to the reference value of String object "2". a and b now
point to the same object.

a is then assigned to/bound to/a pointer to a different object. This in
no way affects the reference value b is bound to. So System.out.println(b)
prints 2 because it remains bound to the reference value of the String
object "2".

c and d both point to the _same object_ which you then _mutate_.

Regards,
Adam

By the way, comp.lang.java.programmer is intended for more advanced Java
programming. Feel free to follow up here but start new topics in
comp.lang.java.help.
 
E

EdwardRF

Alright, if i am not wrong, for each String object there is a
underlying StringBuffer. String is immutable while StringBuffer is not,
as a result, when you reassign a String to a new value, actually it is
assigning itself point to another StringBuffer for its value.

Thus in your code
b=a
actually let B points to a StringBuffer object which A is pointing
to.
a="3"
will make A points to a new StringBuffer that has value "3", while B
is still pointing to the StringBuffer that has value of "2".

EdwardRF

Adam said:
class Test{
public static void main(String args[]){
String a = new String( "2" ), b;
b = a;
a = "3";
System.out.println( b );

String c[]= { "1","2","3" }, d[];
d = c;
c[0] = "4";
System.out.println( d[0] );
}
}

in my opinion ,i thought it will print
3
4
but in fact ,it printed
2
4


who can tell me why?

Java is strictly pass by value and assignment by value. You do need to
appreciate the difference between passing and assigning a primitive value
and passing and assigning a reference value. Reference values are pointers
to objects and objects may be mutated.

In outcome 1, a is a pointer to (the reference value of) String object "2".
b is assigned to the reference value of String object "2". a and b now
point to the same object.

a is then assigned to/bound to/a pointer to a different object. This in
no way affects the reference value b is bound to. So System.out.println(b)
prints 2 because it remains bound to the reference value of the String
object "2".

c and d both point to the _same object_ which you then _mutate_.

Regards,
Adam

By the way, comp.lang.java.programmer is intended for more advanced Java
programming. Feel free to follow up here but start new topics in
comp.lang.java.help.
 
P

Patricia Shanahan

class Test{
public static void main(String args[]){
String a = new String( "2" ), b;

Declare two variables a and b, both type reference to String, and
initialize a with a pointer to a newly created String with content "2".

Copy the pointer to "2" from a to b.

Change a to point to the String literal "3".
System.out.println( b );

Print the String b points at.
String c[]= { "1","2","3" }, d[];

Declare variables c and d to be references to arrays of String
references. Create an array of String references containing pointers to
the literals "1", "2", and "3", and initialize c with a pointer to it.

Copy the pointer to the array from c to d.
c[0] = "4";

Change the first element of the array to point to the literal "4".
System.out.println( d[0] );

Print the String pointed to by the first element of the array pointed to
by d.
}
}

in my opinion ,i thought it will print
3

Why did you expect this?
 
P

Patricia Shanahan

EdwardRF said:
Alright, if i am not wrong, for each String object there is a
underlying StringBuffer. String is immutable while StringBuffer is not,
as a result, when you reassign a String to a new value, actually it is
assigning itself point to another StringBuffer for its value.

The source code for String and StringBuffer are in the src.zip in any
JDK download. They are distinct classes. A String does not have any
fields of type StringBuffer.
Thus in your code
b=a
actually let B points to a StringBuffer object which A is pointing
to.

b cannot, ever, point to a StringBuffer. Its declared type is String, so
it can only be null, or point to a String object. String is final, so it
cannot even point to an object of a subclass of String.

However, I do agree with your approach of thinking in terms of what the
reference variables point at.

The immutability of String does not matter. The following program gets
exactly the same results, using StringBuffer instead of String throughout:

public class TestStringBuffer {
public static void main(String args[]) {
StringBuffer a = new StringBuffer("2"), b;
b = a;
a = new StringBuffer("3");
System.out.println(b);

StringBuffer c[] = { new StringBuffer("1"), new StringBuffer("2"),
new StringBuffer("3") }, d[];
d = c;
c[0] = new StringBuffer("4");
System.out.println(d[0]);
}
}

Patricia
 
R

Roedy Green

class Test{
public static void main(String args[]){
String a = new String( "2" ), b;
b = a;
a = "3";
System.out.println( b );

String c[]= { "1","2","3" }, d[];
d = c;
c[0] = "4";
System.out.println( d[0] );
}
}

in my opinion ,i thought it will print
3
4
but in fact ,it printed
2
4
First rewrite your code in more idiomatic Java. You are using the old
C mixed prefix/postfix syntax. I added some comments that might
clarify.

String a = "2"; // a points to an object "2"
String b = a; // b also points to that same object
a = "3"; // a points to a new object "3"
System.out.println( b ); // print what b points to: "2"

String[] c = { "1","2","3" }; // c points to an object 1,2,3
String[] d = c; // d points to that same object 1,2,3
c[0] = "4"; // modify the first slot of the object so it becomes 4,2.3
System.out.println( d[0] ), // display the first slot of the object: 4
 
R

Roedy Green

Alright, if i am not wrong, for each String object there is a
underlying StringBuffer.

There is no underlying StringBuffer, but there is an underlying
char[]. However, mutability has nothing to do with the apparent
paradox.

In the first case he is modifying a reference to an object. In the
second he is modifying the object itself.
 
D

Dimitri Maziuk

(e-mail address removed) sez:
class Test{
public static void main(String args[]){
String a = new String( "2" ), b;
b = a;
a = "3";
System.out.println( b );
.... prints "2"

char *two = "2";
char *three = "3";
char *a = two;
char *b = a;
a = three;
printf( "%s\n", b );

Dima
 
T

tom fredriksen

Roedy said:
First rewrite your code in more idiomatic Java. You are using the old
C mixed prefix/postfix syntax. I added some comments that might
clarify.

What do you mean? The only thing you did with the code was to change it
to declare one variable on each line. Such things are generally
considered to be a personal preference issue. You shouldn't mix idioms
into it like its a rule or part of the java spec.

/tom
 
R

Roedy Green

What do you mean? The only thing you did with the code was to change it
to declare one variable on each line.

I did that, and changed declarations from
int x[] to int[] x style

The multi vars per line introduces some nasty gotchas. It usually is
not a good idea, especially when declaring arrays.
 
R

Roedy Green

Such things are generally
considered to be a personal preference issue.

The old mixed prefix/postfix syntax was a temporary sop to C
programmers to make them feel at home. Using it in Java is a bit like
using "Thee" and "thou" in English. It marks you as from another era.
 
T

tom fredriksen

Roedy said:
The multi vars per line introduces some nasty gotchas. It usually is
not a good idea, especially when declaring arrays.

You are talking about this line?

String c[]= { "1","2","3" }, d[];

What nasty stuff are you thinking of?

/tom
 
T

tom fredriksen

Roedy said:
The old mixed prefix/postfix syntax was a temporary sop to C
programmers to make them feel at home. Using it in Java is a bit like
using "Thee" and "thou" in English. It marks you as from another era.

Sorry, but no. Thats your preference and feelings. Its still legal
syntax. Writing the following is a similar issue.

int []iArr
int[] iArr
int iArr[]

I agree that there are issues with these different syntaxes for both my,
yours and other examples. But, some issues are personal taste and other
can be misunderstood. Example:

int[] iArr,jArr // readability issue: are both arrays?
int i=5, b; // no issue, can not be misunderstood
int iArr[] and
int []iArr // no issue, both are just personal taste.

int iArr[] = {1,2}, jArr[] = {3,4}
and
int iArr[] = {1,2}
int jArr[] = {3,4}

The first example is a bit less readable than the last two, but no
issue just preference.


/tom
 
O

Oliver Wong

tom fredriksen said:
Roedy said:
The multi vars per line introduces some nasty gotchas. It usually is
not a good idea, especially when declaring arrays.

You are talking about this line?

String c[]= { "1","2","3" }, d[];

What nasty stuff are you thinking of?

Probably something like this:

<dangerousCode>
String []c = {"1", "2", "3"}, d[];
</dangerousCode>

Here it looks like d is array of String, but actually it's an array of array
of String.

- Oliver
 
R

Roedy Green

Sorry, but no. Thats your preference and feelings. Its still legal
syntax. Writing the following is a similar issue.

It is legal, but so are lower case class names, capitalised locals and
\u package names. Being legal does not make it accepted practice.
Look what Sun does.

The only people who use that syntax are C-speaking newbies to Java. If
you adopt that anachronism, people will presume you are a C-speaking
newbie to Java. If you don't mind that, and you think the old syntax
is preferable, go ahead. You will mildly irritate others by refusing
to use the more common idiom, the same way you would if you ignored
the caps conventions. It just trips people up to have things
specified a different way than they expect.

You could also use reverse indentation too. That's legal, but will
make people do a double take to understand your code.
 
M

Monique Y. Mudama

The only people who use that syntax are C-speaking newbies to Java.
If you adopt that anachronism, people will presume you are a
C-speaking newbie to Java. If you don't mind that, and you think the
old syntax is preferable, go ahead. You will mildly irritate others
by refusing to use the more common idiom, the same way you would if
you ignored the caps conventions. It just trips people up to have
things specified a different way than they expect.

If you're talking about doing something like

int b = 5,
c = 7,
d = 8;

... I do that all the time. And I have way more experience in
Java than C. Make of that what you will.

When you have class names that are 20, 30, or more characters
long, I see no reason to type them more often than necessary ...
even with autocomplete, you do have to type a little bit.
 
P

Patricia Shanahan

Monique Y. Mudama wrote:
....
When you have class names that are 20, 30, or more characters
long, I see no reason to type them more often than necessary ...
even with autocomplete, you do have to type a little bit.

You either think a lot faster or type a lot slower than I do when
programming.

Except when using punch cards, with no backspace-erase, I've never been
limited by typing speed. I can type at least enough to keep an
autocomplete happy in less time than it take me to think up a good
variable identifier.

Patricia
 
M

Monique Y. Mudama

Monique Y. Mudama wrote: ...

You either think a lot faster or type a lot slower than I do when
programming.

Except when using punch cards, with no backspace-erase, I've never
been limited by typing speed. I can type at least enough to keep an
autocomplete happy in less time than it take me to think up a good
variable identifier.

Oh ... I wasn't really talking about typing speed.

I type a lot, a whole lot, so anything I don't have to type is great.
I use tab complete in irc to complete five letter nicks!

Also, wasteful repetition irritates me. You know how it's annoying to
see someone repeat the same set of instructions several times, rather
than iterating over the data set? I feel that way, only to a lesser
degree, about unnecessarily repeating types. If it helps the clarity
to split things up with new entries, that's great. I just don't think
that

int i, j;

is any less clear than

int i;
int j;

To me, the second version is actually less clear, because I have to
notice the type for both. Granted, both aren't exactly difficult to
read.
 

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,763
Messages
2,569,563
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top