final,toString,getClass,finalize,hashcode,equals()

由于继承中有一个现象:方法重写。

所以父类的功能,就会被子类给覆盖掉。

有些时候,我们不想让子类去覆盖掉父类的功能,只能让他使用。

针对这种情况,Java提供了一个关键字:final

final:最终的意思。它可以修饰类,方法,变量。

一.

final特点:

final 可以修饰类,该类不能被继承。

final 可以修饰方法,该方法不能被重写。

final 可以修饰变量,变量就变成了常量,只能被赋值一次。

 

 final 修饰局部变量问题

      基本类型:值不能改变。

      引用类型:地址值不能被改变。

 

  final 修饰变量的初始化时机

        1.被final修饰的变量只能赋值一次

        2.在构造方法完毕前。(非静态的常量)

 二.

重写ToString()方法

Object的toString()方法帮助我们返回一个字符串,这个字符串的格式是固定的:类名@hashcode。

作用:返回该对象的字符串表示,默认情况下的数据对我们来说没有意义,一般建议重写该方法。

代码

package com.atguigu.day10;

public class Person {
    private String name;
    private int age;
    private double height;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    public Person(String name, int age, double height) {
        this.name = name;
        this.age = age;
        this.height = height;
    }
    @Override
    public String toString(){
        return "name:"+name+" age:"+age+" height:"+height;
    }
}

main

package com.atguigu.day10;

public class Test {

    public static void main(String args[]) {
        Person p1 = new Person("lin1",23,1.80);
        System.out.println(p1.toString());

    }
}

输出

name:lin1 age:23 height:1.8

 三.getClass

getClass:获取运行时类型
package com.atguigu.day10;

public class Person {
    private String name;
    private int age;
    private double height;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    public Person(String name, int age, double height) {
        this.name = name;
        this.age = age;
        this.height = height;
    }
    @Override
    public String toString(){
        return "name:"+name+" age:"+age+" height:"+height;
    }

    public void eat(){
        System.out.println("just eating");
    }
}

class Student extends Person{
    public Student(String name, int age, double height) {
        super(name, age, height);
    }

    @Override
    public void eat() {
        System.out.println("student eat");
    }
}

main

package com.atguigu.day10;

public class Test {

    public static void main(String args[]) {
        Person p1 = new Person("lin1",23,1.80);
        System.out.println(p1.toString());

        Person p2 = new Student("lin2",19,1.80);
        Class class1 = p2.getClass();
        System.out.println(class1);

    }
}

输出:

name:lin1 age:23 height:1.8
class com.atguigu.day10.Student

 

四.finalize
垃圾回收机器(Garbage Collection),也叫GC,垃圾回收器主要有一下特点:

当对象不再被程序所使用的时候,垃圾回收器将会将其回收
垃圾回收是在后台运行的,我们无法命令垃圾回收器马上回收资源,但是我们可以告诉他可以尽快回收资源(System.gc()和Runtime.getRuntime().gc())
垃圾回收器在回收某个对象的时候,首先会调用该对象的finalize()方法
GC主要针对堆内存
单例模式的缺点


finalize()是Object里面的一个方法,当一个堆空间中的对象没有被栈空间变量指向的时候,这个对象会等待被java回收:jdk里面是这样实现的:

protected void finalize() throws Throwable { }
}

代码:

public class testFinalize
{
    public static void main(String[] args){
    
        Person p = new Person();
        p = null;//此时堆当中的Person对象就没有变量指向了,就变成了垃圾,等到垃圾回收机制调用的finalize()的时候会输出
        
    }
}

class Person
{

    protected void finalize() throws Throwable{
        
        System.out.println("回收了!!!");
    }

}

执行后,垃圾回收机制都没有启动,可以适当建议启动

public class testFinalize
{
    public static void main(String[] args){
    
        Person p = new Person();
        p = null;
        System.gc();


    }
}

class Person
{

    protected void finalize() throws Throwable{
        
        System.out.println("回收了!!!");
    }

}

依然不好使

public class testFinalize
{
    public static void main(String[] args){
    
        Person p = new Person();
        
        for(int i = 0 ; i< 1000; i++){
           p = null;    
        }        
        System.gc();//增加垃圾回收器启动的概率
    }
}

class Person
{

    protected void finalize() throws Throwable{
        
        System.out.println("回收了!!!");
    }

}

 输出:

回收了!!!

 

 hashcode

public class HashCode {
    /*
    hashCode:用于返回当前对象的hash码
    如果两个对象的hash值是不同的,那么这两个对象一定不相等
    如果两个对象的hash值是相同的,那么这两个对象不一定相等
    由于不同的对象可能产生hash码可能一样,所以重写让不同对象的hash码不同
    */
    public static void main(String[] args) {
        
        Person p1 = new Person("lin1",23,1.80);
        int hcode = p1.hashCode();
        System.out.println(hcode); //输出460141958

     


    }
}

 五.equals()

==和equals()在object类默认是都是比较地址值
==:比较基本数据类型,比较的是实际的值,比较引用数据类型,比较的是地址值
equals:重写前比较的是地址值,重写后比较属性值

作用:用于比较两个对象是否相同

注意:重写equals时第一件事就是判断给定的对象是否和当前对象为同一类型。不是同一类型直接返回false,不具有可比性。
equals比较前需要进行安全验证,确保给定的对象不是null,obj若是null,说明该引用变量没有指向任何对象,那么就不能引用obj所指向对象(因为对象不存在)的属性或方法,若这么做会引发NullPointerException,空指针异常!
代码:
package com.atguigu.day10;

public class Demo3 {
    public static void main(String[] args) {
        Student1 s1=new Student1("lin1",18);
        Student1 s2=new Student1("lin1",18);
        Student1 s3=new Student1("lin2",18);
        System.out.println("s1.equals(s2)"+s1.equals(s2));
        System.out.println("s1.equals(s3)"+s1.equals(s3));
    }
}

class Student1{
    String name;
    int age;
    public Student1(String name,int age){
        this.name=name;
        this.age=age;
    }
    @Override
    public boolean equals(Object obj){
        if(this==obj){
            return true;
        }
        if(!(obj instanceof Student1)){
            return false;
        }
        Student1 objStudent=(Student1)obj;
        if(this.name.equals(objStudent.name) && this.age==objStudent.age){
            return true;
        }
        return false;
    }
}

如果不重写equals,则输出结果都是false,重写后第一个是true,第二个是false

另外:因为浮点数存储的是约数,不建议使用==比较浮点类型

 

 

posted @ 2021-11-06 19:33  从此重新定义啦  阅读(38)  评论(0编辑  收藏  举报