f*****g 发帖数: 887 | 1 ArrayList s = new ArrayList();
s.add("abcd");
s.get(0)应该返回reference of the String object, 为啥不能直接s.get(0) = “”
, 而是需要s.set(0,“”) |
z****e 发帖数: 54598 | 2 s是一个reference,存在stack里面
指向heap里面的一块
s.get的值存在stack里面
你让s.get(0) = ""
其实修改的是stack里面的值
=就是给stack里面的一个位置赋值
而你要修改的list对象体存在heap里面
包括第一个位置的reference值
修改stack有啥意义? |
z****e 发帖数: 54598 | 3 s.get(0)其实是一个内存地址
就是一个reference,不是一个变量
s.get(0) = ""毫无意义
reference value = another reference value? |
f*****g 发帖数: 887 | 4 谢谢,但是还是confuse
s.get(0)返回的是指向heap中一个内存区块吧?存的是那个string object |
B*****t 发帖数: 335 | 5 这
【在 z****e 的大作中提到】 : s是一个reference,存在stack里面 : 指向heap里面的一块 : s.get的值存在stack里面 : 你让s.get(0) = "" : 其实修改的是stack里面的值 : =就是给stack里面的一个位置赋值 : 而你要修改的list对象体存在heap里面 : 包括第一个位置的reference值 : 修改stack有啥意义?
|
r****y 发帖数: 26819 | 6 你这个问题其实跟ArrayList无关,这里的关键是,array[i]是一个variable,它可以
用来做lvalue,而s.get(i)是一个value,它不能用来做lvalue。所以你不能把s.get(i)
当作array[i]来看。
【在 f*****g 的大作中提到】 : 谢谢,但是还是confuse : s.get(0)返回的是指向heap中一个内存区块吧?存的是那个string object
|
g*****g 发帖数: 34805 | 7 You can do
s.get(0).setXXX if setXXX is availalbe for the object. String is immutable
and doesn't have such function.
【在 f*****g 的大作中提到】 : 谢谢,但是还是confuse : s.get(0)返回的是指向heap中一个内存区块吧?存的是那个string object
|
f*****g 发帖数: 887 | 8 s.get(i)返回的不是指向那个String object的reference吗?
(i)
【在 r****y 的大作中提到】 : 你这个问题其实跟ArrayList无关,这里的关键是,array[i]是一个variable,它可以 : 用来做lvalue,而s.get(i)是一个value,它不能用来做lvalue。所以你不能把s.get(i) : 当作array[i]来看。
|
r****y 发帖数: 26819 | 9 没错,返回的是一个reference,但关键问题是,这个reference是一个value,不是一个
variable,它不能拿来做assignment expression的左边来指向另一个值。它唯一的功能
是向你提供它指向的object的值。
【在 f*****g 的大作中提到】 : s.get(i)返回的不是指向那个String object的reference吗? : : (i)
|
d****i 发帖数: 4809 | 10 rodney说得是对的,get()返回的是rvalue,不能作为lvalue来赋值。而a[i]就不一样
了,既可以作rvalue,又可以做lvalue,你看一下C++的
const T& get() const;
和
T& get() const;
就知道不同之处了,Java的底层就是C++写的, 所以是同一个道理。
【在 f*****g 的大作中提到】 : ArrayList s = new ArrayList(); : s.add("abcd"); : s.get(0)应该返回reference of the String object, 为啥不能直接s.get(0) = “” : , 而是需要s.set(0,“”)
|
|
|
l**********n 发帖数: 8443 | 11 @Test
public void testAssign(){
class Foo{
private String bar;
public String getBar() {
return bar;
}
public void setBar(String bar) {
this.bar = bar;
}
}
Foo foo = new Foo();
foo.setBar("foobar");
// foo.getBar() = "foobarfoo"; IDE will complain lacking lvalue
String s = foo.getBar();
s = "foobarfoo";
Assert.assertTrue(!s.equals(foo.getBar()));
} |
r****y 发帖数: 26819 | 12 是这么回事。有意思的是,java里不讲lvalue和rvalue,用的是variable和value这两
个词。JLS里说variable指的是一个存储地址及其相关类型,或者叫编译类型。(4.12)
variable是用来hold一个value的。而return expression返回的一定是个value。(14.
17)
【在 d****i 的大作中提到】 : rodney说得是对的,get()返回的是rvalue,不能作为lvalue来赋值。而a[i]就不一样 : 了,既可以作rvalue,又可以做lvalue,你看一下C++的 : const T& get() const; : 和 : T& get() const; : 就知道不同之处了,Java的底层就是C++写的, 所以是同一个道理。
|
r****y 发帖数: 26819 | 13 一般会报:required variable, found value
【在 l**********n 的大作中提到】 : @Test : public void testAssign(){ : class Foo{ : private String bar; : public String getBar() { : return bar; : } : public void setBar(String bar) { : this.bar = bar; : }
|
d****i 发帖数: 4809 | 14 哈哈,不知道还有这个讲法,学习了。
【在 r****y 的大作中提到】 : 是这么回事。有意思的是,java里不讲lvalue和rvalue,用的是variable和value这两 : 个词。JLS里说variable指的是一个存储地址及其相关类型,或者叫编译类型。(4.12) : variable是用来hold一个value的。而return expression返回的一定是个value。(14. : 17)
|
z****e 发帖数: 54598 | 15 你把java的stack&heap好好看看
s.get(0)是一个reference value
这个reference value就是内存中的heap的一个地址
比如heap里面有一个内存块,地址是0xaabbcc88
那么这个值存在stack里面,对应着一个variable,比如s
当你要用这个s的时候,就从stack里面找到这个地址
然后根据这个地址去找heap的那个内存块,然后读取heap内存块里面的各种值
值得注意的是,这个heap块本身,也可能存放有其他heap块的地址
比如如果s里面存放各种变量的其实是一个array,array[0]就是一个variable
这个variable就有一个存放地址的部分,这个部分指向另外一个heap内存块
这个heap内存块是string也就可能是""
这里面array本身也是一个heap块
所以s.get(0)其实是先从stack中找到s在heap中的地址
然后从s在heap中的地址找到array在heap中的地址,然后再从array在heap中的地址中
找到第一个变量的地址,然后找到这个变量在heap中的位置,然后读取值
这里指针指来指去,很容易晕,而arraylist本身是抽象化后实现高级逻辑的结果
你问的问题涉及jvm和arraylist本身的实现,非常底层的问题
不是那么容易回答的
【在 f*****g 的大作中提到】 : 谢谢,但是还是confuse : s.get(0)返回的是指向heap中一个内存区块吧?存的是那个string object
|
z****e 发帖数: 54598 | 16 楼主先把
s = ""是怎么回事想明白
s.charAt(0)这个整个内存逻辑怎么实现想出来再说
arraylist的实现要在这个基础上复杂两层 |
c********h 发帖数: 18 | 17 String is immutable, so you can't use assignment operation to change the
value. |
r****y 发帖数: 26819 | 18 你这个例子举得不错,还可以更清楚一点,别用String,随便换一个自定义的class比如
二维平面点Point,那么问题就很明白,跟String无关,跟ArrayList无关。
换一句大白话说:
任何一个java method的返回结果都不是variable,而只有variable才能够作为
assignment等号的左边。
【在 l**********n 的大作中提到】 : @Test : public void testAssign(){ : class Foo{ : private String bar; : public String getBar() { : return bar; : } : public void setBar(String bar) { : this.bar = bar; : }
|
z****e 发帖数: 54598 | |
z****e 发帖数: 54598 | |
|
|
f*****g 发帖数: 887 | 21 ArrayList s = new ArrayList();
Point t = new Point();
t.x = 3;
t.y = 4;
s.add(t);
s.get(0).x = 4;
work, right?
比如
【在 r****y 的大作中提到】 : 你这个例子举得不错,还可以更清楚一点,别用String,随便换一个自定义的class比如 : 二维平面点Point,那么问题就很明白,跟String无关,跟ArrayList无关。 : 换一句大白话说: : 任何一个java method的返回结果都不是variable,而只有variable才能够作为 : assignment等号的左边。
|
s****y 发帖数: 503 | 22
可以是可以 但是x和y在Point中一般是private的
所以还是需要get和set方法的
你这样的写法在Java里应该是不推荐的
【在 f*****g 的大作中提到】 : ArrayList s = new ArrayList(); : Point t = new Point(); : t.x = 3; : t.y = 4; : s.add(t); : s.get(0).x = 4; : work, right? : : 比如
|
z*******3 发帖数: 13709 | 23 .x就是一个变量
.x不是方法,你看它没有括号
方法的返回值一定不是一个变量,而是一个value或者说是reference
无脑的记忆方式就是,等号左边的最后一个东西,它不能以括号结尾
除非是==,单独的=,左边一定是一个变量,.x,x,.y,abc,i,t,point etc.
如果是point()=...这种,就是错的
【在 f*****g 的大作中提到】 : ArrayList s = new ArrayList(); : Point t = new Point(); : t.x = 3; : t.y = 4; : s.add(t); : s.get(0).x = 4; : work, right? : : 比如
|
r****y 发帖数: 26819 | 24 不是一码事啊。
car != carpet
【在 f*****g 的大作中提到】 : ArrayList s = new ArrayList(); : Point t = new Point(); : t.x = 3; : t.y = 4; : s.add(t); : s.get(0).x = 4; : work, right? : : 比如
|
z****e 发帖数: 54598 | 25 .的意思是先找到heap所在的内存块
然后取那个variable
t.x
t的值放在stack里面
.的话,系统就会定位到heap中去
然后t.x就定位到heap里面x这个variable
t.x = ***意思就是修改heap里面这个variable的值
t.get(0).x
也是类似的
t.get(0)返回一个reference,然后系统根据这个reference value
定位heap中的内存块,然后.x就是找到这个内存块中的x变量
.get(0)这个还涉及到去method区取方法体
楼主还是要先理解内存中的几个不同的区
stack, heap这些,不理解这些,怎么说都是虚的 |