首页 > 编程语言 > 详细

Java的API及Object类中的方法

时间:2020-04-04 19:09:46      阅读:63      评论:0      收藏:0      [点我收藏+]

目录

什么是API?
Object类中的toString()方法
Object类中的equals()方法
String类中重写了toString()方法和equals()方法
equals()方法深层次剖析
Object类中的finalize()方法
Object类中的hashCode()方法

什么是API?

应用程序編程接口。(Application Program Interface)
整个JDK的类库就是一个javase的API,每一个API都会配置一套API帮助文档。

Object类中的toString()方法

  • 关于object类中的toString()方法
    1、源代码长什么样?
public string tostring(){
return this.getclass().getName () + "@" + Integer.toHexstring (hashcode ());
}

源代码上toString()方法的默认实现是:类名@对象的内存地址转换为十六进制的形式。
2、toString()方法的设计目的是:
通过调用这个方法可以将一个"Java对象"转换成‘‘字符串”。
3、其实SUN公司开发Java语言的时候,建议所有的子类都去重写toString()方法应该是一个简洁的、详实的、易阅读的。

  • 代码例子
package com.zyh.ToString;

public class MyTime {
    int year;
    int month;
    int day;
    public MyTime(){
    }
    public MyTime(int year, int month, int day){
        this.year = year;
        this.month = month;
        this.day = day;
    }
    /*重写toString()方法*/
    public String toString(){
        return this.year + "年" + this.month + "月" + this.day + "日";
    }
}
package com.zyh.ToString;

public class MyTimeTest {
    public static void main(String[] args) {
        MyTime t1 = new MyTime(1999,3, 10);
        System.out.println(t1);
        /*直接输出结果为:
        com.zyh.ToString.MyTime@74a14482*/
        String s1 = t1.toString();
        System.out.println(s1);
        /*重写toString()方法后,输出结果为:
        1999年3月10日*/
        System.out.println(t1);
        /*可以省略后面的.toString()方法,默认调用。
        输出结果同上*/
    }
}
  • toString()方法都是要重写的!

Object类中的equals()方法

  • equals()方法的源代码
public boolean equals(Object obj) {
    return (this == obj);
}

以上这个方法是object类的默认实现。在object类中的equals方法当中,默认采用的是"=="判断两个java对象是否相等。

  • SUN公司设计equals方法的目的是什么?
    以后编程的过程当中,都要通过equals方法来判断两个对象是否相等。equals方法是判断两个对象是否相等的。
  • 代码例子
package com.zyh.ToStAndEquals;

public class Eqs {
    int year;
    int month;
    int day;
    public Eqs(){
    }
    public Eqs(int year, int month, int day){
        this.year = year;
        this.month = month;
        this.day = day;
    }
    /*默认的equals方法
    public boolean equals(Object obj) {
    return (this == obj);
    }*
}
package com.zyh.ToStAndEquals;

public class EqsTest {
    public static void main(String[] args) {
        int a = 10;
        int b = 10;
        System.out.println(a == b);
        Eqs e1 = new Eqs(2020, 3, 25);
        Eqs e2 = new Eqs(2020, 3, 25);
        System.out.println(e1 == e2);
    }
}

由于e1、e2中保存的对象内存地址不同,所以输出:
技术分享图片

  • 由以上结果得出:
    判断两个java对象是否相等,不能使用"==",因为它比较的是两个对象的内存地址。
  • 而在object类中的equals方法当中,默认采用的是"=="判断两个java对象是否相等。所以原本的equals方法不够用,需要子类重写equals方法
  • 重写后的代码:
package com.zyh.ToStAndEquals;

public class Eqs {
    int year;
    int month;
    int day;
    public Eqs() {
    }
    public Eqs(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }
    //重写equals方法
    public boolean equals(Object obj) {
        int year1 = this.year;
        int month1 = this.month;
        int day1 = this.day;
        if (obj instanceof Eqs){
            Eqs m1 = (Eqs) obj;
            int year2 = m1.year;
            int month2 = m1.month;
            int day2 = m1.day;
            if (year1==year2&&month1==month2&&day1==day2){
                return true;
            }
        }
        return false;
    }
}
package com.zyh.ToStAndEquals;

public class EqsTest {
    public static void main(String[] args) {
        int a = 10;
        int b = 10;
        System.out.println(a == b);
        Eqs e1 = new Eqs(2020, 3, 25);
        Eqs e2 = new Eqs(2020, 3, 25);
        System.out.println(e1 == e2);
        //重写equals方法后
        boolean flag = e1.equals(e2);
        System.out.println(flag);
    }
}

输出:
技术分享图片

  • 改良上面的equals方法
    public boolean equals(Object obj){
        //如果obj是空,直接返回false
        if (obj==null){
            return false;
        }
        //如果oj不是一个Eqs。没必要比较了,直接返回false
        if (!(obj instanceof Eqs)){
            return false;
        }
        /*如果this和obj保存的内存地址相同,
        没必要比较了,直接返回true。
        内存地址相同的时候指向的堆内存
        的对象肯定是同一个。*/
        if (this == obj){
            return true;
        }
        /*程序能够执行到此处说明:
        obj不是null, obj是Eqs类型*/
        Eqs m1 = (Eqs) obj;
        if (this.year==m1.year && this.month==m1.month && this.day==m1.day){
            return true;
        }
        //程序能到这里返回false
        return false;
        /*再改良
        Eqs m1 = (Eqs) obj;
        return this.year==m1.year && this.month==m1.month && this.day==m1.day;
        */
    }
  • IDEA一键生成equals方法:
    Alt + Ins

String类中重写了toString()方法和equals()方法

  • equals()
    1、String类已经重写了equals方法,比较两个字符串不能使用"==",必须使用equals。equals是通用的。
    2、代码例子:
package com.zyh.ToStAndEquals;

public class Str {
    public static void main(String[] args) {
        String s1 = "zyh";
        String s2 = "zyh";
        System.out.println(s1 == s2);/*这里是true,
        原因是因为String是sun亲生的,所以双引是常量,
        常量和常量用等就是true,方法区有个常量池。*/
        String s3 = new String("yu");
        String s4 = new String("yu");
        System.out.println(s3 == s4);//false
        System.out.println(s3.equals(s4));//true;
    }
}
  • 关于Java中的String为什么是不可变的?
    链接:
    String源码分析
  • toString()
    1、String类已经重写了toString方法。
    2、代码例子:
package com.zyh.ToStAndEquals;

public class Str {
    public static void main(String[] args) {
        String x = new String("zhang");
        System.out.println(x.toString());//输出:zhang
        System.out.println(x);//输出:zhang
    }
}
  • 结论
    1、java中基本数据类型比较是否相等,可以使用"=="判断
    2、java中所有的引用数据类型统一使用equals方法来判断是否相等。

equals()方法深层次剖析

  • 代码示例:
package com.zyh.EqsPro;

import java.util.Objects;

public class Address {
    String city;
    String street;
    String zipcode;

    public Address() {
    }
    public Address(String city, String street, String zipcode) {
        this.city = city;
        this.street = street;
        this.zipcode = zipcode;
    }
    /*这里也要进行对equals的重写,
    否则比较的就是u1、u2中的Address的
    内存地址,而不是内容
    */
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Address address = (Address) o;
        return city.equals(address.city) &&
                street.equals(address.street) &&
                zipcode.equals(address.zipcode);
    }
    /*重写toString方法,保证输出的Address
    是指定内容,而不是哈希值。
    */
    @Override
    public String toString() {
        return "Address{" +
                "city=‘" + city + ‘\‘‘ +
                ", street=‘" + street + ‘\‘‘ +
                ", zipcode=‘" + zipcode + ‘\‘‘ +
                ‘}‘;
    }
}
package com.zyh.EqsPro;

import java.util.Objects;

public class User {
    String name;
    Address addr;
    public User() {
    }
    public User(String name, Address addr) {
        this.name = name;
        this.addr = addr;
    }
    @Override
    public boolean equals(Object o) {
    /*u2传进来的时候发生了类型自动转换,
    转换成了Object类型。
    */
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return this.name.equals(user.name) &&
                this.addr.equals(user.addr);
        /*这里的equals是this.name字符串里的equals方法,
        不是equals方法里面又用equals方法*/
    }
    @Override
    public String toString() {
        return "User{" +
                "name=‘" + name + ‘\‘‘ +
                ", addr=" + addr +
                ‘}‘;
    }
}
package com.zyh.EqsPro;

public class Test {
    public static void main(String[] args) {
        User u1 = new User("zhang", new Address("CD", "px","111"));
        User u2 = new User("zhang", new Address("CD", "px","111"));
        System.out.println(u1.equals(u2));
        System.out.println(u1);
    }
}
  • 由以上代码可得出:
    重写要彻底!

Object类中的finalize()方法

  • 源码:
protected void finalize() throws Throwable { }
  • 特征:
    1、finalize()方法只有一个方法体,里面没有代码,而且这个方法是protected修饰的。这个方法不需要程序员手动调用, JVM的垃圾回收器负责调用这个方法。
    2、不像equals、toString,、equals和toString ()方法是需要你写代码调用的。finalize()只需要重写,重写完将来自动会有程序来调用。(GC负责调用finalize()方法)
  • finalize()方法的执行时机:
    当一个java对象即将被垃圾回收器回收的时候,垃圾回收器负责调用finalize()方法。
  • 垃圾销毁时机
    finalize()方法实际上是SUN公司为java程序员准备的一个时机,垃圾销毁时机。
    如果希望在对象销毁时机执行一段代码的话,这段代码要写到finalize ()方法当中。
  • 示例代码:
package com.zyh.FinalizeDemo;

public class Person {
    protected void finalize() throws Throwable {
        /*重写finalize()方法。
        Person类型的对象被垃圾回收器回收的时候,
        垃圾回收器负责调用:p.finalize()*/
        System.out.println(this + "垃圾被回收!");
        /*项目开发中有这样的业务需求:
        所有对象在JVM中被释放的时候,记录释放时间*/
    }
}
package com.zyh.FinalizeDemo;

public class Test {
    public static void main(String[] args) {
        Person p = new Person();
        p = null;
        /*提示:ava中的垃圾回收器不是轻易启动的,
        垃圾太少,或者时间没到。
        种种条件下,有可能启动,也有可能不启动。
        例如:家里的垃圾桶不会有垃圾就去倒*/

        //制造大量垃圾,使其启动
        for (int i = 1; i < 1000000; i++) {
            Person q = new Person();
            q = null;
        }

        System.gc();
        /*建议启动垃圾回收器,提高启动的概率
        (只是建议,可能不启动,也可能启动)*/
    }
}

Object类中的hashCode()方法

  • 源码
public native int hashCode();

这个方法不是抽象方法,带有native关键字,底层调用C+程序。

  • hashCode()方法返回的是哈希码:
    实际上就是一个java对象的内存地址,经过哈希算法,得出的一个值。所以hashCode()方法的执行结果可以等同看做一个java对象的内存地址。
  • 代码示例
    public static void main(String[] args) {
        Object o = new Object();
        System.out.println(o.hashCode());
        //输出:1956725890
        Object o1 = new Object();
        System.out.println(o1.hashCode());
        //输出:356573597
        /*对象内存地址经过哈希算法转换的一个数字,
        可以等同看做内存地址。*/
    }

Java的API及Object类中的方法

原文:https://www.cnblogs.com/yu011/p/12632727.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!