Java基础——处理对象

来源:互联网 发布:网络测试与故障诊断 编辑:程序博客网 时间:2024/05/16 09:36

Java对象都是Object类的实例,都可直接调用该类中定义的方法,这些方法提供了处理Java对象的通用方法。

一、打印对象和toString方法

先看下面程序。

class Person{    private String name;    public Person(String name)    {        this.name = name;    }}public class PrintObject{    public static void main(String[] args)    {        //创建一个Person对象,将之赋给p变量        Person p =new Person("孙悟空");        //打印p所引用的Person对象        System.out.println(p);    }}

上面程序创建了一个Person对象,然后使用System.out.println()方法输出Person对象。编译运行上面程序,看到如下结果:

Person@15db9742

当运行上面程序时,可能看到不同的输出结果:@符号后的8位十六进制数字可能发生改变。但这个输出结果是怎么来的呢?System.out.println()方法只能在控制台输出字符串,而Person实际上是内存中的对象,怎么能直接转换为字符串输出呢?当使用该方法输出Person对象时,实际上输出的是Person对象的toString()方法的返回值。也就是说,下面两行代码的效果完全一样。

System.out.println(p);System.out.println(p.toString());

toString()方法时一个非常特殊的方法,它是一个“自我描述”方法,该方法通常用于实现这样一个功能:当程序员直接打印该对象时,系统将会输出该对象的“自我描述”信息,用以告诉外界该对象具有的状态信息

Object类提供的toString()方法总是返回该对象实现类的“类名 + @ + hashCode”值。

因此如果用户需要自定义实现“自我描述”的功能,就必须重写Object类的toString()方法,例如下面程序。

class Apple{    private String color;    private double weight;    public Apple()    {    }    public Apple(String color , double weight)    {        this.color = color;        this.weight = weight;    }    //省略color、weight的setter和getter方法    ...    //重写toString()方法    public String toString()    {        return "一个苹果,颜色是:" + color +            ",重量是:" + weight;    }}public class ToStringTest{    public static void main(String[] args)    {        Apple a  = new Apple("红色" , 5.68);        //打印Apple对象        System.out.println(a);    }}

一个苹果,颜色是:红色,种类是5.68

这个toString()方法提供了足够有效信息来描述Apple对象,也就实现了toString()方法的功能。

二、==和equals方法

Java程序测试两个变量是否相等有两种方式:一种是利用==运算符;另一种是利用equals()方法

当使用==来判断两个变量是否相等时如果两个变量是基本类型变量,且都是数值类型(不一定要求数据类型完全相同),则只要两个变量的值相等,就返回true。

但对于两个引用类型变量,只要它们指向同一个对象时,==判断才会返回true

==不可用于比较类型上没有父子关系的对象。下面程序示范了使用==来判断两种类型变量是否相等的结果。

public class EqualTest{    public static void main(String[] args)    {        int it = 65;        float fl = 65.0f;        //将输出true        System.out.println("65和65.0f是否相等" + (it == f1));        char ch = 'A';        //将输出true        System.out.println("65和'A'是否相等?" + (it == ch));        String str1 = new String("hello");        String str2 = new String("hello");        //将输出false        System.out.println("str1是否等于str2?"+(str1==str2));        //将输出true        System.out.println("str1是否equals str2?" +            (str1.equals(str2)));    }}

运行上面程序,可以看到65、65.0f和’A’相等。但对于str1和str2,因为它们都是引用变量,它们分别指向两个通过new关键字创建的String对象,因此str1和str2两个变量不相等。

String还有一个非常容易迷惑的地方:”hello”直接量和new String(“hello”)有什么区别呢?
当Java程序直接使用形如”hello”的字符串直接量(包括可以在编译时就计算出来的字符串值)时,JVM将会使用常量池来管理这些字符串;当使用new String(“hello)时,JVM会先使用常量池来管理”hello”直接量,再调用String类的构造器来创建一个新的String对象,新创建的String对象会被保存在堆内存中。换句话说,new String(“hello”)一共产生了两个字符串对象。

提示:常量池(constant pool)专门用于管理在编译时被确定并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口中的常量,还包括字符串常量。

下面程序示范了JVM使用常量池来管理字符串直接量的情形:

public class StringCompareTest{    public static void main(String[] args)    {        //s1直接引用常量池中的"Java"        String s1 = "学习Java";        String s2 = "学习";        String s3 = "Java";        //s4后面的字符串值可以在编译的时候就确定下来        //s4直接引用常量池中的"学习Java"        String s4 = "学习" + "Java";        //s5后面的字符串值可以在编译的时候就确定下来        //s5直接引用常量池中的"疯狂Java"        String s5 = "疯" + "狂" + "Java";        //s6后面的字符串值不能在编译时就确定下来        //不能引用常量池中的字符串        String s6 = s2 + s3;        //使用new构造器将会创建一个新的String对象        //s7引用堆内存中新创建的String对象        String s7 = new String("疯狂Java");        System.out.println(s1 == s4);//输出true        System.out.println(s1 == s5);//输出true        System.out.println(s1 == s6);//输出false        System.out.println(s1 == s7);//输出false    }}

JVM常量池保证相同字符串直接量只有一个,不会产生多个副本。
例子中的s1、s4、s5所引用的字符串可以在编译期就确定下来,因此它们都将引用常量池中的同一个字符串对象。

使用new String()创建的字符串对象时运行时创建出来的,它被保存在运行时内存区(即堆内存)内,不会放入常量池中。

但在很多时候,程序判断两个引用变量是否相等,也希望有一种类似于“值相等”的判断规则,并不严格要求两个引用变量指向同一个对象。

equals()方法时Objectg类提供的一个实例方法,因此所有引用变量都可调用该方法来判断是否与其他引用变量相等。但这个使用方法判断两个对象相等的标准与使用==运算符没有区别,同样要求引用变量指向同一个对象才会返回true。因此这个Object类提供的equals()方法没有太大的实际意义。如果希望采用自定义的相等标准,可以采用重写equals方法来实现。

提示:
String已经重写了Objetc的equals()方法,String的equals()方法比较两个字符串相等的标准是:只要两个字符串所包含的字符序列相同,通过equals()比较将返回true,否则返回false

0 0
原创粉丝点击