Day13 Object类,包装类

本文详细介绍了Java中的多态性,包括instanceof操作符的使用、子类调用特有方法的方式以及类型转换规则。讲解了低级别到高级别自动转换和高级别到低级别强制转换的注意事项,强调了在向下转型前使用instanceof判断以避免ClassCastException。此外,还探讨了Object类的重要方法如clone、equals、finalize、hashCode和toString,以及它们在不同场景下的应用。同时,文章对比了==和equals()的区别,并解释了在自定义类中重写equals()方法的一般原则。最后,提到了final、finally和finalize的区别,并展示了包装类的转换以及自动装箱和拆箱的特性。单元测试的使用方法和包装类在实际编程中的应用也有所提及。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Day13

instanceof 操作符(关键字)

x instanceof A //检验x是不是A类对象,返回值为 boolean
// 要求 x 和 A 必须是 	子类父类的关系,否则编译错误

子类调用特有的方法

在多态的应用时,内存中实际上已经加载了子类特有的属性方法。但由于变量声明是父类类型,导致编译时只能调用的父类中定义过的方法,子类特有的方法不能调用。

可以使用强制类型转换将对象赋值给子类对象,从而调用子类特有的方法。

Person - > Man
Person p = new Man();
p.eat(); // Right
p.earnMoney(); // Wrong
Man m = p; // Wrong
Man m = (Man)p; // Wrong
m.earnMoney();// Right

低->高 自动,高->低 强制

使用强制转换,可能ClassCastException异常

此时需要使用instanceof判断

为了避免出现ClassCastException异常,在向下转型之前进行instanceof判断

如果,x instanceof A :true,x instanceof B:true 则AB也可以进行转换

向下转型要求 new 的是 子类

Object类

  • Object类是所有java类的根父类
  • 如果在类的声明中没有使用extends指明其父类,默认继承java.lang.Object类
  • Object类中声明的功能(属性,方法)具有通用性
  • Object类中声明了一个空参构造器

方法:

  1. clone()
  2. equals()
  3. finalize()垃圾回收,在没有对象指向的时候自动执行,然后执行垃圾回收机制==子类重写此方法,可以在释放对象前进行一些操作
  4. getClass()获得自身的类
  5. int hashCode()返回自身哈希值
  6. toString()返回内存值?打印对象值时调用

== 和 equals()区别

== :

  1. 可以使用在 基本数据类型变量 和 引用数据类型变量中

    比较特别的,10 == 10.0 : ture

  2. 当比较的是基本数据类型,比较两个变量保存的数据是否相(不一定要类型相同)

    当比较的是引用数据类型,比较两个对象的地址值是否相同,即两个引用是否指向同一个对象主体。

equals():

  1. 是一个java.lang.Object的方法,而非运算符

  2. 只适用于引用数据类型 (不能用于引用数据类型

  3. Object类中equals()的定义

     public boolean equals(Object obj){
        return (this == obj);
    }
    //说明:Object类中定义的equals()和==的作用是相同的,比较两个对象的地址值是否相同,即两个引用是否指向相同对象
    //即:若没有重写,默认为==
    
    
  4. 像String,Date,File,包装类等,都重写了Object类equals()方法。重写以后,比较的不是地址值,而是两个对象的实体是否相同。

  5. 通常情况下,我们自己定义的类使用equals(),通常也是比较两者实体内容是否都相同,我们应当自行重写该函数。

    重写的原则:比较两个对象的实体内容(需要强制转换)

    • 对称性:x.equals(y) <-> y.equals(x)

    • 自反性: x.equals(x)

    • 传递性: x.equals(y) ,y.equals(z) -> x.equals(z)

    • 一致性: 可重复

    • 任何情况下,x.equals(null) :false

      ​ x.equals(与x不同的类的对象):false

    可以使用IDE的自动生成equals()

    所以Answer:

  6. ==既可以比较基本数据类型,也可以比较引用数据类型,对于基本数据类型比较值,对于引用数据类型是比较内存地址

  7. equals的话,属于java.lang.Object类的方法,如果该方法没有重写,默认等同于==,我们可以看到,String等类的equals()的方法都是被重写过的,而且String类在日常开发中用的比较多,久而久之,形成了equals就是比较值的错误观点

  8. 具体看自定义类型及其父类中有没有重写equals方法类判断

  9. 通常,重写equals方法,要比较类中的相应属性是否都相等

final ,finally,finalize 区别?

toString()

  1. 当我们输出一个对象的引用,实际调用该对象的toString()

  2. Object类中toString()的定义:

    public String toString(){
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }
    
  3. 像String,Date,File,包装类等都重写类Object类中的toString()方法

    使得调用对象的toString()时,返回“实体内容”信息

单元测试的使用方法

Java中的JUnit单元测试

步骤:

  1. 创建Java类,进行单元测试

    Java类的要求:

    • 此类为public
    • 此类提供公共的无参构造器
  2. 此类中声明单元测试方法

    权限为public,没有返回值,没有形参

  3. 此单元此时方法上需声明注解:@Test,并在单元测试类中导入 org.junit.Test;

  4. 声明单元测试方法以后,可以在方法体中测试相关方法

  5. 写完,双击测试方法,run as JUnitTest

    绿条-无异常;红条-异常;

包装类的使用(Wrapper)

  • 针对八种基本数据类型定义对应的引用类型——包装类(封装类)
  • 有了类的特点,就可以调用类中的方法,Java才是真正面向对象

基本数据类型,String类,包装类的转换

// 基本数据类型 - 》包装类
public void test1(){
    int num1 = 10;
    Integer in1 = new Integer(num1);
    
    Integer in2 = new Integer("123");
    
    Integer in3 = new Integer("123abc"); // Wrong
    
    Integer in4 = new Integer(123);
    
    Float f1 = new Float("123.0F");
    
    Float f2 = new Float(123.0F);
    
    Boolean b1 = new Boolean(true);
    
    Boolean b2 = new Boolean("true123");  // 可通过,但b2.value : false;
    
}

//包装类->基本数据类型
public void test2(){
    Integer in1 = new Integer(123);
    int i1 = in1.intValue();
}

JDK5.0 新增特性 自动装箱,自动拆箱

// 自动装箱
int num1 = 10;
Integer in1 = num1;

// 自动拆箱
Integer in1 = 10;
int num1 = in1;

但是,仍然不能像C++重载运算符那样直接进行运算符运算

String类型 <- 基本数据类型,包装类调用String重载的方法valueOf()

String类型 -> 基本数据类型,包装类调用包装类的parseXxx(String s)方法

  • 对于Number类的,可能发生NumberFormatException,可能提供的String含有非数字内容
  • boolean则非true即false

关于包装类使用的面试题:

下列两组代码输出结果相同么?分别是什么?

public class day13 {
    public static void main(String[] args){
        Object o1 = true ? new Integer(1) : new Double(2.0);
        Object o2;
        if(true)
            o2 = new Integer(1);
        else
            o2 = new Double(2.0);

        System.out.println("o1 : " + o1);
        System.out.println("o2 : " + o2);
        System.out.println("o1 : " + o1 + " o2 : " + o2);
		// 输出为  1.0 1 
        // 这里注意 三目运算符 会自动将 ‘:’ 两侧的 数据类型统一
    }
}

判断输出结果?

Integer x = new Integer(1);
        Integer y = new Integer(1);
        System.out.println(x == y); // false
        Integer m = 1;
        Integer n = 1;
        System.out.println(m == n); // true
        Integer p = 128;
        Integer q = 128;
        System.out.println(p == q); // false
        // 对于较小的 数字  -128~127 ,Integer中封装类一个数组,存储这些数字的位置,也就是说,当处于这个范围时,其地址相同
        // 超出这个范围,则转换为 new 对象的形式,地址值自然不同
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值