请教!关于java堆栈和数据存储的问题?

snyy20 2007-09-30 06:51:47

我知道JAVA中基本数据类型直接放在栈中,而用new关键字产生的对象的值放在堆中,栈中放一份此对象堆中地址的引用。


我现在有一点不明白,看如下java代码:

int i=10;
int j=10;
System.out.print(i==j);

不用说,上面的输入出是:true;

问题是:上面声明了两个变量,都给了初始值,栈应该为它们分配两个地址才对啊?
i==j 只有在引用同一个栈地址时,才会返回true;这是为什么?还是栈有其它的处理方式?

请各位高手赐教!!!


...全文
236 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
aidejieti 2007-10-05
  • 打赏
  • 举报
回复
越看越糊涂了..~~但是,,还是抓住一点就OK了..~~~
joejoe1991 2007-10-01
  • 打赏
  • 举报
回复
equals 方法是object类的方法 默认也是比较引用的
只不过大多数类都重写了object类的equals方法 和hashcode 所以成了比较具体的值了
比如String a=new String("aaa"); String b=new String("aaa");
a.equals(b);///true

如果是你自己写的类没有重写equals方法 那它也是比较引用的!
比如:

public class Untitled1 {
public static void main(String[] args) {
A a=new A();
A b=new A();

System.out.println(a.equals(b));
}
}

class A{
String str="aaaa";

}

类A继承自object 并用它声明了两个对象。 用a 和 b指向这两个对象 然后调用equals方法比较
虽然两个对象的str值是相等的 。 不过结果还是false; 因为object类equals方法默认是比较引用 显然a和b指向的两个不同的对象。所以false;
这时 如果改一下代码

public class Untitled1 {
public static void main(String[] args) {
A a=new A();
A b=new A();

System.out.println(a.equals(b));
}
}

class A{
String str="aaaa";

public boolean equals(A a)
{
if (a.str.equals(this.str))
{
return true;
}

return false;
}
}

重写了equals方法 这时返回的就是true 当然 我这里是为了省事。。 更标准的应该再重写hashcode方法


== 用于对象之间的比较时 比较的是引用。 就是比较操作符两边是不是同一个对象
比如:Date date=new Date();
Date date2=new Date();
date==date2; ///false

== 用在基本数据类型之间的时候 比的是值 。 基本数据类型并不是对象。
shadao 2007-09-30
  • 打赏
  • 举报
回复
equal()什么意思?

指示其他某个对象是否与此对象“相等”。
equals 方法在非空对象引用上实现相等关系:

自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。
对称性:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true。
传递性:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true。
一致性:对于任何非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改。
对于任何非空引用值 x,x.equals(null) 都应返回 false。
Object 类的 equals 方法实现对象上差别可能性最大的相等关系;即,对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true(x == y 具有值 true)。


==什么意思?
对于原始类型(int,short,char,long,float,double,boolean..)而言表示他们的值是否相同
对于object而言,表示他们所指向到引用是否相同
zephyr_cc 2007-09-30
  • 打赏
  • 举报
回复
String s1=new String(“JDK1.2”);
String s2=new String(“JDK1.2”);

s1和s2是引用类型,它们是局部变量,是存在栈里面的。
就像i里面放的是10一样
s1里面就是放了一个值,这个值就是那个String对象的地址
所以s1==s2也就是比较了这两个值和i,j没区别。
看看下面这段程序:
public class Test75 {
public static void main(String[] args) {
String s1 = "123";
String s2 = "123";
System.out.println(s1 == s2);
Object o = (Object)s2;
System.out.println(s1 == o);
}
}
snyy20 2007-09-30
  • 打赏
  • 举报
回复
基本类型是在栈里面的。

现在是对象类型,它在比较的时候是直接拿栈中的信息进行比较的!
还是通过栈拿到堆里的地址或信息进行比较的?
zephyr_cc 2007-09-30
  • 打赏
  • 举报
回复
int i=10;
int j=10;
这两个10都是放在栈里面的
snyy20 2007-09-30
  • 打赏
  • 举报
回复
那也就是只操作栈中的值, 没有把堆拉进来了?
zephyr_cc 2007-09-30
  • 打赏
  • 举报
回复
打错了:
“和上面是一样的,s1==s2在虚拟机看来不过是s1放个地址,s2放个地址,把两个地址拿出来看看一不一样”
和上面是一样的,s1==s2在虚拟机看来不过是位置1放个地址,位置2放个地址,把两个地址拿出来看看一不一样
zephyr_cc 2007-09-30
  • 打赏
  • 举报
回复
引用类型里面存放的是什么?
是他所指向的对象的地址。
那地址是什么?
不也是值吗?

==这东西哪有那么智能
他就是看左右这两个东西一不一样。

局部变量
int i=10;
int j=10;
这个i,j两个名字是给程序员编程用的,
虚拟机用不着,也根本看不到。
i==j在虚拟机看到不过是位置1放个10,位置2放个10,把两个10拿出来看看一不一样

String s1=new String(“JDK1.2”);
String s2=new String(“JDK1.2”);
和上面是一样的,s1==s2在虚拟机看来不过是s1放个地址,s2放个地址,把两个地址拿出来看看一不一样
snyy20 2007-09-30
  • 打赏
  • 举报
回复
我这样理解不知道对不对!请各位大虾们赐教!!

== 在比较时 都是拿比较双方在栈中的值。

基本类型就在栈中,所以比较取的就是它在栈中的值。

new 出来的的对象类型的值存放在堆中,在栈中存有一个此对象在堆中的引用,在程序操作的时候都是在
使用栈中的引用。所以比较时会取得它在栈中的引用的值。所以会将堆中的值压进栈中进行比较。

kekeemx 2007-09-30
  • 打赏
  • 举报
回复
Object这个超类里的equals方法直接是返回a==b的结果的.即它直接用==比较两个变量.
而string类则覆盖了object里边这个方法,它是比较两个string的具体内容是否一致的..
其实==在比较基本数据类型的时候直接比较两个数值是否相等.而对于对象之间的比较,==则是
比较这2个是否指向同一个在堆中的数据
snyy20 2007-09-30
  • 打赏
  • 举报
回复
你的意思是: == 在比较对象的时候是拿它们在堆中的地址进行比较,比较基本类型就是拿它们在栈中的值来比较;
对吗?


你说的是String里的equals()方法,这个方法是重写了Object的equals()方法,所以是比较的是堆中存放的数据。

但object 里的equals()方法又和"=="有什么异同呢?

xiangfeidecainiao 2007-09-30
  • 打赏
  • 举报
回复
只要是 用 关键字 new 出来的都是对象,对象是在堆中.
对象就是一小快内存 指向 一大快内存
比如 String s0 = new String("abc");
其实是 s0 = 对象在堆内存的的地址;
String s1 = new String("abc");
s1 = 对象在堆内存的的地址;

每个new出来的对象的内存的地址是不一样的...

== : 是比较2个值,所以s0==s1比较的是
s0对象在堆内存的地址 是不是等于 s1对象在堆内存的地址
所以是False

equals():是所有类的祖先Object的一个空实现方法,String类继承了他,并重写了equals()方法让equals()去比较String类对象的内容,所以,我们调用的时候是比较的是S0和S1中的内容(堆内存中存放的数据)

你可以看 API String类 的 equals()方法.
snyy20 2007-09-30
  • 打赏
  • 举报
回复
你都乱了!就不要说我了,干脆这样,你就说说原问题吧,“说说==与equals()方法的区别。”

给个详细的解释! 谢谢!
shadao 2007-09-30
  • 打赏
  • 举报
回复
说得都乱了
一个是jvm的堆栈
一个是实际处理器的堆栈
shadao 2007-09-30
  • 打赏
  • 举报
回复
处理器实际运算的时候自然将这个值(在堆里的引用)推入栈内

无论什么运算都一样,数据都经过栈进入寄存器的
shadao 2007-09-30
  • 打赏
  • 举报
回复
堆里的引用
snyy20 2007-09-30
  • 打赏
  • 举报
回复
那如果是两个object对象呢?

String s1=new String(“JDK1.2”);
String s2=new String(“JDK1.2”);

Sysout.out.print(s1==s2);
这个时候用==比较的是堆还是栈里的值?
////////
而对对象使用==比较的是引用,所以这里答案是false
-------------------------------------------------

你说的引用是指栈里的引用吗?
shadao 2007-09-30
  • 打赏
  • 举报
回复
我现在有一点不明白,看如下java代码:

int i=10;
int j=10;
System.out.print(i==j);

不用说,上面的输入出是:true;

问题是:上面声明了两个变量,都给了初始值,栈应该为它们分配两个地址才对啊?
i==j 只有在引用同一个栈地址时,才会返回true;这是为什么?还是栈有其它的处理方式?

请各位高手赐教!!!

///////////
这是因为对原始类型的数据比较的时候 比较的是他的值而不是地址














那如果是两个object对象呢?

String s1=new String(“JDK1.2”);
String s2=new String(“JDK1.2”);

Sysout.out.print(s1==s2);
这个时候用==比较的是堆还是栈里的值?
////////
而对对象使用==比较的是引用,所以这里答案是false











String s1=(“JDK1.2”);
String s2=(“JDK1.2”);

Sysout.out.print(s1==s2);
/////////
这个答案是true
而这个例子告诉我们 s1 s2是指向同1引用

这是因为jvm提供了一个空间,可称之为 字符串标准引用区
又编译器直接赋值的都指向 字符串标准引用区












String s1=new String(“JDK1.2”);
String s2=new String(“JDK1.2”);

Sysout.out.print(s1.intern()==s2.intern());
//////////////
这个答案是true

因为intern()返回的是字符串标准引用区

你可以参考下String.intern()方法









lz这下了解了么?
snyy20 2007-09-30
  • 打赏
  • 举报
回复
那如果是两个object对象呢?

String s1=new String(“JDK1.2”);
String s2=new String(“JDK1.2”);

Sysout.out.print(s1==s2);


这个时候用==比较的是堆还是栈里的值?
加载更多回复(2)

62,612

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧