Java之基本类型和引用类型、引用传递和值传递、“==”和equals()
2015-04-11 12:24
423 查看
作者:金良(golden1314521@gmail.com) csdn博客:http://blog.csdn.net/u012176591
Java中数据类型分为两大类,是基本类型和对象类型。相应的,变量也就有两种类型:基本类型和引用类型。
基本类型的值就是一个数字,一个字符或一个布尔值。引用类型,是一个对象类型的啊,它的值是指向内存空间的引用,就是地址,所指向的内存中保存着变量所表示的一个值或一组值。
Java的基本数据类型如下表所示,其余的都是对象类型,如String类型、Integer类型、数组类型等。
变量的基本类型和引用类型的区别:
基本数据类型在声明时系统就给它分配空间。
举个例子:
[java] view
plaincopy
int a;
a=10;//正确,因为声明a时就分配了空间
而引用与之不同,它声明时只给变量分配了引用空间,而不分配数据空间。
举个例子:
[java] view
plaincopy
MyDate today;
today.day = 4; //发生错误,因为today对象的数据空间未分配。
那我们怎么给它赋值啊?引用类型变量在声明后必须通过实例化开辟数据空间,才能对变量所指向的对象进行访问。举个例子:
[java] view
plaincopy
MyDate today; //将变量分配一个保存引用的空间
today = new MyDate(); //执行new MyDate(),给today变量开辟数据空间,然后把空间的首地址传给today变量
today.day = 4;//正确,执行赋值操作,
引用类型变量的赋值过程图解如下:
这是赋值过程的代码:
[java] view
plaincopy
MyDate a,b; //在内存开辟两个引用空间
a = new MyDate();//开辟MyDate对象的数据空间,并把该空间的首地址赋给a
b = a; //将a存储空间中的地址写到b的存储空间中
这是赋值过程的图示:
引用类型:除了在函数传值的时候是"引用传递",在任何用"="向对象变量赋值的时候都是"引用传递"。
值传递:基本类型的传递都属于值传递,和C语言一样,当把Java的基本数据类型(如int,char,double等)作为入口参数传给函数体的时候,传入的参数在函数体内部变成了局部变量,这个局部变量是输入参数的一个拷贝,所有的函数体内部的操作都是针对这个拷贝的操作,函数执行结束后,这个局部变量也就完成了它的使命,它影响不到作为输入参数的变量。这种方式的参数传递被称为"值传递"。
引用传递举例(注释有分析):
[java] view
plaincopy
package bupt.xujinliang.mydatatest;
/**
*
* @author jin
*
*/
class MyDate {
String Year;
String Month;
String Day;
String Date;
public MyDate(){
Year = "2014";
Month ="06";
Day = "14";
Date = Year + "." + Month + "."+ Day;
}
public String toString(){
return Date;
}
}
public class MyDateTest {
MyDate mydate1 = new MyDate();//new一个对象,开辟数据空间
MyDate mydate2 = mydate1;// 赋值语句,使 mydate1和 mydate2将指向同一内存空间
MyDate mydate3 = new MyDate();//重新new一个对象,则mydate3和mydate1是指向不同的内存空间的:
public void changeDate(MyDate mydate){
mydate.Date = "2014.09.26";
}
public static void main(String[] args) {
MyDateTest mydatetest = new MyDateTest();
System.out.println("Before call changeDate() method: ");
System.out.println("\tmydate1: " + mydatetest.mydate1);
System.out.println("\tmydate2: " + mydatetest.mydate2);
System.out.println("\tmydate3: " + mydatetest.mydate3);
mydatetest.changeDate(mydatetest.mydate1);
System.out.println("After call changeDate() method: ");
System.out.println("\tmydate1: " + mydatetest.mydate1);
System.out.println("\tmydate2: " + mydatetest.mydate2);//赋值语句,二者将指向同一内存空间
System.out.println("\tmydate2: " + mydatetest.mydate3);//与前者不指向同一内存空间
}
}
上述程序的输出:
了解了前边所讲的基本数据类型和引用类型的概念,下面讲下Java中“==”和equals的区别。
二者对比如下:
上面的列表中的引用数据类型需要注意一下,引用数据类型可以指8种基本数据类型以外的所有类,所以它是无限的,在Java API中出现的类中的绝大部分都重写了equals()方法,都满足表中引用数据类型的要求;不过当你写了一个自己的类,默认情况下是没有重写equals()方法的,这种情况稍后会讲到。
代码:
[java] view
plaincopy
package bupt.xujinliang.equalsexample;
/**
*
* @author jin
*
*/
public class EqualsExample {
public static void main(String[] args) {
Integer obj1 = new Integer(5);
Integer obj2 = new Integer(15);
Integer obj3 = new Integer(5);
Integer obj4 = obj2;
System.out.println("obj1.equals(obj1):\t"+obj1.equals(obj1));//true
System.out.println("obj1.equals(obj2):\t"+obj1.equals(obj2));//false
System.out.println("obj1.equals(obj3):\t"+obj1.equals(obj3));//true
System.out.println("obj2.equals(obj4):\t"+obj2.equals(obj4));//true
System.out.println("----------------------------------");
System.out.println("obj1==obj1:\t"+(obj1==obj1));//true
System.out.println("obj1==obj2:\t"+(obj1==obj2));//false
System.out.println("obj1==obj3:\t"+(obj1==obj3));//false
System.out.println("obj2==obj4:\t"+(obj2==obj4));//true
}
}
运行效果:
但是,对于一般的Object类,或者用户自己写的Java类,默认其equals()方法就是采用==进行比较的,所以二者等效为同一个对象为真,否则为假。那么为什么上述的引用变量类型Integer的equals()方法和==不等效呢,因为它重写了equals方法,所以才有上述代码的运行结果。
这面的类没有重写equals()方法:
[java] view
plaincopy
package bupt.xujinliang.equalsobject;
/**
*
* @author jin
*
*/
class MyObject {
int num;
MyObject(int num) {
this.num = num;
}
}
public class EqualsObject {
public static void main(String[] args) {
MyObject myobj1 = new MyObject(5);
MyObject myobj2 = new MyObject(15);
MyObject myobj3 = new MyObject(5);
MyObject myobj4 = myobj1;
MyObject myobj5 = myobj2;
MyObject myobj6 = myobj3;
System.out.println("myobj1.equals(myobj1):\t"+myobj1.equals(myobj1));//true
System.out.println("myobj1.equals(myobj2):\t"+myobj1.equals(myobj2));//false
System.out.println("myobj1.equals(myobj3):\t"+myobj1.equals(myobj3));//false
System.out.println("myobj2.equals(myobj4):\t"+myobj2.equals(myobj4));//false
System.out.println("----------------------------------");
System.out.println("myobj1==myobj1:\t"+(myobj1==myobj1));//true
System.out.println("myobj1==myobj2:\t"+(myobj1==myobj2));//false
System.out.println("myobj1==myobj3:\t"+(myobj1==myobj3));//false
System.out.println("myobj2==myobj4:\t"+(myobj2==myobj4));//false
}
}
上述代码的运行结果如下图所示,可以看到用equals()方法和==是等效的。
下面我们对MyObject类的equals()方法做如下重写:
[java] view
plaincopy
public boolean equals(Object obj) {
if(this == obj)//如果是同一个实例,则相等
return true;
if(null == obj) //如果obj为空,则不相等
return false;
if(getClass() != obj.getClass()) //如果类型不同,则不相等
return false;
MyObject other = (MyObject)obj;
if(num == other.num) //当类仅有的整型成员变量相等时,相等
return true;
return false;
}
重新运行程序,则结果如下所示:
1.引用类型和基本类型
Java中数据类型分为两大类,是基本类型和对象类型。相应的,变量也就有两种类型:基本类型和引用类型。基本类型的值就是一个数字,一个字符或一个布尔值。引用类型,是一个对象类型的啊,它的值是指向内存空间的引用,就是地址,所指向的内存中保存着变量所表示的一个值或一组值。
Java的基本数据类型如下表所示,其余的都是对象类型,如String类型、Integer类型、数组类型等。
变量的基本类型和引用类型的区别:
基本数据类型在声明时系统就给它分配空间。
举个例子:
[java] view
plaincopy
int a;
a=10;//正确,因为声明a时就分配了空间
而引用与之不同,它声明时只给变量分配了引用空间,而不分配数据空间。
举个例子:
[java] view
plaincopy
MyDate today;
today.day = 4; //发生错误,因为today对象的数据空间未分配。
那我们怎么给它赋值啊?引用类型变量在声明后必须通过实例化开辟数据空间,才能对变量所指向的对象进行访问。举个例子:
[java] view
plaincopy
MyDate today; //将变量分配一个保存引用的空间
today = new MyDate(); //执行new MyDate(),给today变量开辟数据空间,然后把空间的首地址传给today变量
today.day = 4;//正确,执行赋值操作,
引用类型变量的赋值过程图解如下:
这是赋值过程的代码:
[java] view
plaincopy
MyDate a,b; //在内存开辟两个引用空间
a = new MyDate();//开辟MyDate对象的数据空间,并把该空间的首地址赋给a
b = a; //将a存储空间中的地址写到b的存储空间中
这是赋值过程的图示:
2.引用传递 和 值传递
引用类型:除了在函数传值的时候是"引用传递",在任何用"="向对象变量赋值的时候都是"引用传递"。值传递:基本类型的传递都属于值传递,和C语言一样,当把Java的基本数据类型(如int,char,double等)作为入口参数传给函数体的时候,传入的参数在函数体内部变成了局部变量,这个局部变量是输入参数的一个拷贝,所有的函数体内部的操作都是针对这个拷贝的操作,函数执行结束后,这个局部变量也就完成了它的使命,它影响不到作为输入参数的变量。这种方式的参数传递被称为"值传递"。
引用传递举例(注释有分析):
[java] view
plaincopy
package bupt.xujinliang.mydatatest;
/**
*
* @author jin
*
*/
class MyDate {
String Year;
String Month;
String Day;
String Date;
public MyDate(){
Year = "2014";
Month ="06";
Day = "14";
Date = Year + "." + Month + "."+ Day;
}
public String toString(){
return Date;
}
}
public class MyDateTest {
MyDate mydate1 = new MyDate();//new一个对象,开辟数据空间
MyDate mydate2 = mydate1;// 赋值语句,使 mydate1和 mydate2将指向同一内存空间
MyDate mydate3 = new MyDate();//重新new一个对象,则mydate3和mydate1是指向不同的内存空间的:
public void changeDate(MyDate mydate){
mydate.Date = "2014.09.26";
}
public static void main(String[] args) {
MyDateTest mydatetest = new MyDateTest();
System.out.println("Before call changeDate() method: ");
System.out.println("\tmydate1: " + mydatetest.mydate1);
System.out.println("\tmydate2: " + mydatetest.mydate2);
System.out.println("\tmydate3: " + mydatetest.mydate3);
mydatetest.changeDate(mydatetest.mydate1);
System.out.println("After call changeDate() method: ");
System.out.println("\tmydate1: " + mydatetest.mydate1);
System.out.println("\tmydate2: " + mydatetest.mydate2);//赋值语句,二者将指向同一内存空间
System.out.println("\tmydate2: " + mydatetest.mydate3);//与前者不指向同一内存空间
}
}
上述程序的输出:
3.“==”和equals()
了解了前边所讲的基本数据类型和引用类型的概念,下面讲下Java中“==”和equals的区别。二者对比如下:
上面的列表中的引用数据类型需要注意一下,引用数据类型可以指8种基本数据类型以外的所有类,所以它是无限的,在Java API中出现的类中的绝大部分都重写了equals()方法,都满足表中引用数据类型的要求;不过当你写了一个自己的类,默认情况下是没有重写equals()方法的,这种情况稍后会讲到。
代码:
[java] view
plaincopy
package bupt.xujinliang.equalsexample;
/**
*
* @author jin
*
*/
public class EqualsExample {
public static void main(String[] args) {
Integer obj1 = new Integer(5);
Integer obj2 = new Integer(15);
Integer obj3 = new Integer(5);
Integer obj4 = obj2;
System.out.println("obj1.equals(obj1):\t"+obj1.equals(obj1));//true
System.out.println("obj1.equals(obj2):\t"+obj1.equals(obj2));//false
System.out.println("obj1.equals(obj3):\t"+obj1.equals(obj3));//true
System.out.println("obj2.equals(obj4):\t"+obj2.equals(obj4));//true
System.out.println("----------------------------------");
System.out.println("obj1==obj1:\t"+(obj1==obj1));//true
System.out.println("obj1==obj2:\t"+(obj1==obj2));//false
System.out.println("obj1==obj3:\t"+(obj1==obj3));//false
System.out.println("obj2==obj4:\t"+(obj2==obj4));//true
}
}
运行效果:
但是,对于一般的Object类,或者用户自己写的Java类,默认其equals()方法就是采用==进行比较的,所以二者等效为同一个对象为真,否则为假。那么为什么上述的引用变量类型Integer的equals()方法和==不等效呢,因为它重写了equals方法,所以才有上述代码的运行结果。
这面的类没有重写equals()方法:
[java] view
plaincopy
package bupt.xujinliang.equalsobject;
/**
*
* @author jin
*
*/
class MyObject {
int num;
MyObject(int num) {
this.num = num;
}
}
public class EqualsObject {
public static void main(String[] args) {
MyObject myobj1 = new MyObject(5);
MyObject myobj2 = new MyObject(15);
MyObject myobj3 = new MyObject(5);
MyObject myobj4 = myobj1;
MyObject myobj5 = myobj2;
MyObject myobj6 = myobj3;
System.out.println("myobj1.equals(myobj1):\t"+myobj1.equals(myobj1));//true
System.out.println("myobj1.equals(myobj2):\t"+myobj1.equals(myobj2));//false
System.out.println("myobj1.equals(myobj3):\t"+myobj1.equals(myobj3));//false
System.out.println("myobj2.equals(myobj4):\t"+myobj2.equals(myobj4));//false
System.out.println("----------------------------------");
System.out.println("myobj1==myobj1:\t"+(myobj1==myobj1));//true
System.out.println("myobj1==myobj2:\t"+(myobj1==myobj2));//false
System.out.println("myobj1==myobj3:\t"+(myobj1==myobj3));//false
System.out.println("myobj2==myobj4:\t"+(myobj2==myobj4));//false
}
}
上述代码的运行结果如下图所示,可以看到用equals()方法和==是等效的。
下面我们对MyObject类的equals()方法做如下重写:
[java] view
plaincopy
public boolean equals(Object obj) {
if(this == obj)//如果是同一个实例,则相等
return true;
if(null == obj) //如果obj为空,则不相等
return false;
if(getClass() != obj.getClass()) //如果类型不同,则不相等
return false;
MyObject other = (MyObject)obj;
if(num == other.num) //当类仅有的整型成员变量相等时,相等
return true;
return false;
}
重新运行程序,则结果如下所示:
相关文章推荐
- Java之基本类型和引用类型、引用传递和值传递、“==”和equals()
- java方法传递引用、传递基本类型
- java中基本类型的参数传递和引用类型的参数传递
- java基本数据类型传递与引用传递的区别详解
- 牛客网Java刷题知识点之基本数据类型参数传递和引用数据类型参数传递图解
- Java传递基本类型:值传递,对象作为参数:引用传递
- 2006-07-28 Java的常用包,"=="和"equals"的用法,基本数据类型与引用类型,对象的克隆
- Java第五课 Java的常用包,"=="和"equals"的用法,基本数据类型与引用类型,对象的克隆。
- java基本数据类型传递与引用传递区别详解(一个大神的解析,不是我。。)
- 【Java】基本类型和引用类型(值传递)
- 【Java基础】基本类型的包装类作为参数传递是值传递还是引用传递
- java基本数据类型传递与引用传递区别详解
- java 中的基本数据类型的传递和引用数据类型的传递
- java基本数据类型传递与引用传递区别详解
- java基本数据类型传递与引用传递区别详解
- java基本数据类型传递与引用传递区别详解
- 由【JAVA中参数传递问题】引发除了基本数据类型和引用类型的思考
- java基本数据类型和引用数据类型的调用传递的区别
- java基本数据类型传递与引用传递区别
- java基本数据类型传递与引用传递区别详解