小生刚学Java,有几个问题硬是没想明白,希望各位前辈能不吝赐教^_^。
【问题1】关于==与equals()
小生对==和equals()的工作方式不太了解,麻烦大家解释下下面的代码的输出值:class MyClass
{
public Integer value1;
}
public class NewClass1 {
public static void main(String[] args) {
Integer a0=new Integer("1");
Integer b0=new Integer("1");
System.out.println("a0==b0: "+(a0==b0));
System.out.println("a0.equals(b0): "+a0.equals(b0));
MyClass a1=new MyClass();
MyClass b1=new MyClass();
a1.value1=b1.value1=2;
System.out.println("a1==b1: "+(a1==b1));
System.out.println("a1.equals(b1): "+a1.equals(b1));
System.out.println("a1.value1==b1.value1: "+(a1.value1==b1.value1));
System.out.println("a1.value1.equals(b1.value1): "+a1.value1.equals(b1.value1));
Object a2=new Object();
Object b2=new Object();
System.out.println("a2==b2: "+(a2==b2));
System.out.println("a2.equals(b2): "+a2.equals(b2));
}
}【问题2】关于交换int值引发的问题
【问题2.1】众所周知,C语言中下面的代码可以用来交换a、b的值,而在Java中,运行结果是a=0,b=3。这是为什么?能不能解释一下Java中运算符的结合性。int a=3;
int b=7;
a^=b^=a^=b;【问题2.2】尝试过使用下面的方法交换两个int值,显然无法成功,这是为什么?能不能解释下Java中对象和基本类型的存储、赋值和参数传递的方式?void Swap(Integer a,Integer b)
{
Integer temp=a;
a=b;
b=temp;
}【问题2.3】Java中如何使用函数交换两个int值,C++和C#中可以用下列方式实现,Java中就无能为力了么?void Swap(int &a,int &b)
void Swap(ref int a,ref int b)【问题3】break label和continue label怎么使用?下面的代码输出什么,为什么没有陷入死循环呢? public static void main(String[] args)
{
loop:
for (int i=1;i<10;++i)
{
System.out.println();
for (int j=i;j<10;++j)
{
if(j==8)
{
continue loop;
}
System.out.print("*");
}
}
}
【问题1】关于==与equals()
小生对==和equals()的工作方式不太了解,麻烦大家解释下下面的代码的输出值:class MyClass
{
public Integer value1;
}
public class NewClass1 {
public static void main(String[] args) {
Integer a0=new Integer("1");
Integer b0=new Integer("1");
System.out.println("a0==b0: "+(a0==b0));
System.out.println("a0.equals(b0): "+a0.equals(b0));
MyClass a1=new MyClass();
MyClass b1=new MyClass();
a1.value1=b1.value1=2;
System.out.println("a1==b1: "+(a1==b1));
System.out.println("a1.equals(b1): "+a1.equals(b1));
System.out.println("a1.value1==b1.value1: "+(a1.value1==b1.value1));
System.out.println("a1.value1.equals(b1.value1): "+a1.value1.equals(b1.value1));
Object a2=new Object();
Object b2=new Object();
System.out.println("a2==b2: "+(a2==b2));
System.out.println("a2.equals(b2): "+a2.equals(b2));
}
}【问题2】关于交换int值引发的问题
【问题2.1】众所周知,C语言中下面的代码可以用来交换a、b的值,而在Java中,运行结果是a=0,b=3。这是为什么?能不能解释一下Java中运算符的结合性。int a=3;
int b=7;
a^=b^=a^=b;【问题2.2】尝试过使用下面的方法交换两个int值,显然无法成功,这是为什么?能不能解释下Java中对象和基本类型的存储、赋值和参数传递的方式?void Swap(Integer a,Integer b)
{
Integer temp=a;
a=b;
b=temp;
}【问题2.3】Java中如何使用函数交换两个int值,C++和C#中可以用下列方式实现,Java中就无能为力了么?void Swap(int &a,int &b)
void Swap(ref int a,ref int b)【问题3】break label和continue label怎么使用?下面的代码输出什么,为什么没有陷入死循环呢? public static void main(String[] args)
{
loop:
for (int i=1;i<10;++i)
{
System.out.println();
for (int j=i;j<10;++j)
{
if(j==8)
{
continue loop;
}
System.out.print("*");
}
}
}
解决方案 »
- JDK6中的List<E>类在继承中怎么用?
- 内部类做监听器的问题<anonymous myframe$1> is not abstract and does not override abstract method actionPerformed
- 在jsp页面如何给javascript中的变量付值
- 有甚麽好的编程网站推介一下?
- 如何获得不重复字符串的总数。并将他们打印出来?
- 如何将一个已存在的照片,添加到Frame上面
- 救命呀!Tomcat怎么下载,我知道网址,不知道都需要哪些文件,帮帮我吧,我快急死了!!!!
- 把string和int型类型转成byte[]类型通过流发送,在客户方如何解码?
- 送分了:"shallow copy" 和"deep copy" 的区别,越详细越好:)
- cmd下java程序编译能通过但是运行不了出异常
- 请问这个字符串如何用正则表达式提取出日期
- jsp验证码
a^=b^=a^=b;这个我以前遇到过,好像最左的^=时a的值用的是原来的值,并不是最右面赋值之后的a的值,为什么是这样,不太清楚.
我是用下面的办法来的解决的,
b^=a^=b;
a^=b;
2.2之所以不能交换是因为,java都是值传递,你在方法中交换两个参数的值,实参的值是不会发生变化的。包装类好像都是常量,不能修改。所以不能通过传 基本类型或其包装类型来交换两个值。
a1.value1==b1.value1: true
a1.value1.equals(b1.value1): true
难道a1.value1与b1.value1地址相同么?但是value1不是静态的呀~~那他们地址为什么相同呢?
break label:转到label处执行,退出break所在的循环,但label处的循环断续。
但是value1是Integer类型呀~~,他们为什么会引用到同一个对象呢?是不是因为这条语句?a1.value1=b1.value1=2;
for (int i=1;i<10;++i)i为什么没有变成1呢?实在是不太明白~~
i的作用域是什么呢?
这个讨论过多次了,
-128~127之间的Integer用的是常量池中的Integer,不会在堆中重新分配新空间的,所以是同一个常量,地址也就相同了。
a1.value1=b1.value1=2;
的过程是:
1、创建一个值为 2 的 int
2、创建一个值为 2 的 Integer(自动装箱)
3、将这个 Integer 对象的引用同时赋给 b1.value1 和 a1.value1所以 b1.value1 和 a1.value1 得到的是同一个对象的引用。
for (int i=1;i<10;++i)
首先 int i=1 只在循环第一次开始的时候执行
i<10 用来判断循环条件是否成立
++i,是每次循环结束之后执行
******
*****
****
***
**
**成功生成(总时间:0 秒)后来我单步跟踪看了,i=9的时候就跳出循环了,不知道为什么~~
【问题1】关于==与equals()
==比较的是地址
equals比较内容和数据类型【问题2.2】尝试过使用下面的方法交换两个int值,显然无法成功,这是为什么?能不能解释下Java中对象和基本类型的存储、赋值和参数传递的方式?
Java code
void Swap(Integer a,Integer b)
{
Integer temp=a;
a=b;
b=temp;
}
【问题2.3】Java中如何使用函数交换两个int值,C++和C#中可以用下列方式实现,Java中就无能为力了么?
public void show(int a, int b) {
a = a + b;
b = a - b;
a = a - b;
}
== 对象比较(对象地址/内容比较)
equals 内容比较
C/C++ code
int a=3;
int b=7;
a^=b^=a^=b;
equals :比较的是值相等,可以是两个不同的对象引用。注意有一点:equals是Object对象的成员方法,也就是说我们可以通过重写equals
改变判断两个对象的值相等的标准,完全有可能两个对象的值理论上不相等(如3!=5)通过
改写equals方法让他们相等。而至于同一个类的两个对象实例为什么不同了,好像是这样的:一个类每生成一个对象
实例就会产生一个序列号,如每个人一生下来就有一个身份证id,这个id正是写在equals
方法中成为判断两个类实例是否相等的标准。还请高人指点上述存在的问题。
当Integer a0=new Integer("1"); 后编译器是把内容“1”放到堆中存放,它的引用放到栈中起名为a0,其中存放的是 “1”中在堆中的地址。
每次new的对象都会这样,无论值是否相同。
a0与b0是两个不同的引用,这里他们也引用着不同的对象(里边存放着堆中不同的地址)。
a0==b0比较的是a0与b0两个引用(即里边存放着堆的地址),所以是不相同的false。
但如果
Integer a0=1;
Integer b0=1; 这样定义
这样定义会把对象放到pool里。java会维护这个对象pool以减少对内存的消耗。当定义b0时候,java会先去pool中查看是否存在该对象,如果有直接返回,否则再new出个新的来。
所以这个a0 == b0 值是true
2.a0.equals(b0): true
当Integer a0=new Integer("1");时,由于你使用的是字符串构造方法
public Integer(String s) throws NumberFormatException {
this.value = parseInt(s, 10);
}
最后会把值放到value属性中。
而在Integer类中equals方法
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
比较的是两个obj从intValue()中得到的value,所以 true
3.a1==b1: false
跟上一个类似你定义两个obj后就存放在堆中具有不同的地址,a1与b1分别引用着不同的地址。用==比较的是引用所以是false
4.a1.equals(b1): false
a1是MyClass类的对象,而在MyClass这个类中并没有对equals方法进行重写,则调用的是父类Obj的原始equals方法
public boolean equals(Object obj) {
return (this == obj);
}
比较的是“引用”所以跟用“==”比较结果相同 是false
5.a1.value1==b1.value1: true
6.a1.value1.equals(b1.value1): true
a1.value1=b1.value1=2; 执行后b1.value1的引用与a1.value1的引用相同,而且他们指向的obj的值都是2.所以 5,6都是true
7.a2==b2: false
8.a2.equals(b2): false
a2与b2都是obj类型,跟前面一样定义两个不同地址的对象,a2与b2引用是不同的。即使他们的值都是null但object类中的equals比较的是引用,故也是不同的。都是false表达能力差了些,也请高手指点
public class Demo {
public static void main(String args[]){
A a=new A();
B b=new B();
System.out.println(a.equals(b));
}
}
class A{
public boolean equals(Object obj){
return true;
}
}
class B{
public boolean equals(Object obj){
return true;
}
}运行结果:
true
关于连等的问题,深层的意思也不是很懂。下面是我的认识,java中就是这么个策略。连等运算
a^=b^=a^=b 与 a = a^b;
b = b^a;
a = a^b; 是不等价的
连等运算是记录初始值的,具体为什么这样?我不知道。但它的策略是这样的
a^=b^=a^=b
等价于a=3^b;b=7^a;a=3^b;每个式子的左边的变量是被初始化的。
a=3^7; --> 4
b=7^4; --> 3
a=3^3; --> 0不知道明白不
java中方法中传值都是引用void Swap(Integer a,Integer b)
{
Integer temp=a;
a=b;
b=temp;
}这里的 a , b 是引用的复制
举个例子加入你的代码是这样的
...
Integer a = new Integer(1);
Integer b = new Integer(2);
//在定义完a,b时候内存中栈是这样的
栈 堆
---- ---------
|a |----->|1 |
---- |2 |
|b |----->| |
|__| |________|
Swap(a,b);
....
当你进入Swap方法里,得到的a,b参数其实不是上面栈中的a,b了。而是两个新的引用可以起名为a1,b1
栈 堆
---- ---------
|a |----->|1 |
---- |2 |
|b |----->| |
|__| --^-------
|a1|--------|
---- ^
|b1|--------|
|__|
a1,b1也指向堆中1,2地址,但在方法中不管你怎么操作,都只是a1,b1两个引用。不会影响到原来的a,b,a,b中的指向并没有因为方法里的折腾而变化。
这就是引用传值与c是不一样的。但如果你改变的是a,b中的property ,这样就会发生变化。为什么呢?
这里传到方法中的依然是引用的复制 a1,b1。但它们的指向是堆中原来的obj,你改变堆中obj的属性,原来的a,b是跟它们的复制指向的是同一个obj。所以都会发生改变
例如public class MyClass {
public Integer value1 ;
}public static void main(String[] args) {
// TODO Auto-generated method stub
MyClass a = new MyClass();
a.value1 = 1;
MyClass b = new MyClass();
b.value1 = 2;
swap(a,b);
System.out.println(a.value1);
System.out.println(b.value1);
}
private static void swap(MyClass a,MyClass b){
a.value1=2;
b.value1=1;
}
输出的结果是 2 ,1 发生了变化
这种情况跟上面的是两回事
你定义loop:只能放在for语句上。
指的是
当执行continue时候,会继续执行loop所在的for上的下一次循环。所以没有重新执行for循环而是接着循环下一次,当然i也就自动加1没有变为初始值。
循环变量的作用域当然是在循环体里了,出了循环就释放掉了。break道理是一样的,只不过是跳出当前循环。你定义的loop是指定执行break时跳出的循环体。所以你这段代码不可能一直重新跑,等最外层的循环执行完也就完了。我回答的是不是你想要问的
[/Quote]没有办法,除非把a,b放入对象内,再把对象的引用传给swap方法.
本来equals造出来就是想比较内容的,但如果你新写一个类的话,不重写equals方法,就会调用Object中的equals方法,而Object中的equals确还是比较地址的,所以这儿就有问题了。
但好比Integer、String这类的就不一样了,因为它们已经重写了equals方法,用来比较内容了,与你新写的类不一样