当前位置: 首页 > article >正文

Java-128陷阱、抽象类和接口的区别、为什么 hashCode()需要和equals()一起重写、封装继承多态

 128陷阱

Integer a = 100;
Integer b = 100;
System.out.println(a==b); //true
Integer c= 1000;
Integer d= 1000;
System.out.println(c==d);//false
int e = 1000;
System.out.println(c==e);//true

分析以上代码运行的结果

源码:

Integer a=128;     

编译器执行的是:Integer a=Integer.valueOf(128); 也就是调用了valueof()方法,进行了自动装箱。

Integer 的 valueOf 方法当中,存储着一个 cache 数组,该数组相当于一个缓存,范围在 -128~127 闭区间。

    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
    private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];
 
        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;
 
            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
 
            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }
 
        private IntegerCache() {}
    }

128陷阱:Integer 数据类型使用“==”比较时,

  • 如果传入的int值在cache缓存-128~127的范围中,则直接返回预先创建好的对象,如果不在范围中,则创建一个新的Integer对象返回。
  • 如果传入value数值在-128~127范围内,那么所有在这个范围内创建的数值相同的Integer变量,实际都指向同一个对象,因此地址也相同,所以用“==”比较的结果为true。
  • 如果传入value数值不在cache范围内,那么每次被创建的对象都是一个新的对象,即通过new关键字由JVM分配新地址。因此地址不相同,所以用“==”比较的结果为false。

抽象类和接口的区别

两者的特点:

  • 抽象类用于描述类的共同特性和行为,可以有成员变量、构造方法和具体方法。适用于有明显继承关系的场景。

  • 接口用于定义行为规范,可以多实现,只能有常量和抽象方法(Java 8 以后可以有默认方法和静态方法)。适用于定义类的能力或功能。

抽象类和接口都不能够实例化,但可以定义抽象类和接口类型的引用。

两者的区别:

  • 实现方式:实现接口的关键字为implements,继承抽象类的关键字为extends。一个类可以实现多个接口,但一个类只能继承一个抽象类。所以,使用接口可以间接地实现多重继承。

  • 方法方式:接口只有定义,不能有方法的实现,java 1.8中可以定义default方法体,而抽象类可以有定义与实现,方法可在抽象类中实现。

  • 访问修饰符:接口成员变量默认为public static final,必须赋初值,不能被修改;其所有的成员方法都是public、abstract的。抽象类中成员变量默认default,可在子类中被重新定义,也可被重新赋值;抽象方法被abstract修饰,不能被private、static、synchronized和native等修饰,必须以分号结尾,不带花括号。

  • 变量:抽象类可以包含实例变量和静态变量,而接口只能包含常量(即静态常量)。

  • 访问类型:抽象类中抽象方法的访问类型可以是public,protected,但接口中抽象方法的访问类型只能是public,并且默认为public abstract(省略则自动默认补全)。

  • 抽象类可以有构造方法,接口中不能有构造方法。 抽象类中可以有静态方法,接口中不能有静态方法。 抽象类中可以有普通方法,接口中所有方法都必须是抽象的。 抽象类中可以有成员变量,接口中没有成员变量。

为什么 hashCode() 需要和 equals() 一起重写?

  • 保证单一原则:equals相同的两个对象的hashcode必须相同。如果重写了equals而没有重写hashcode,会出现equals相同hashcode不相同这个现象。

  • 在无序集合中(如Set),使用hashcode来计算key应存储在hash表的索引,如果重写了equals而没有重写hashcode,会出现两个完全相同的对象。因为hashcode不同,计算出的索引不同,那么这些集合就会混乱。

  • 提高效率,当比较两个对象是否相同时,先比较hashcode是否相同,如果hashcode不相同肯定不是一个对象,如果hashcode相同再调用equals来进行比较,减少了比较次数从而提高效率

封装、继承、多态

Java面向对象的三大特性包括:封装、继承、多态

  • 封装:封装是指将对象的属性(数据)和行为(方法)结合在一起,对外隐藏对象的内部细节,仅通过对象提供的接口与外界交互。封装的目的是增强安全性和简化编程,使得对象更加独立。

  • 继承:继承是一种可以使得子类自动共享父类数据结构和方法的机制。它是代码复用的重要手段,通过继承可以建立类与类之间的层次关系,使得结构更加清晰。

  • 多态:多态是指允许不同类的对象对同一消息作出响应。即同一个接口,使用不同的实例而执行不同操作。多态性可以分为编译时多态(重载)和运行时多态(重写)。它使得程序具有良好的灵活性和扩展性。


http://www.kler.cn/a/534799.html

相关文章:

  • langchain教程-6.TextSplitter/文档切分
  • 问卷调查系统Two-Step-Kmeans-前端后端搭建完成
  • docker安装es及分词器ik
  • 开源AI智能名片2 + 1链动模式S2B2C商城小程序:内容价值创造与传播新引擎
  • 图论常见算法
  • 北大AGI与具身智能评估新范式!Tong测试:基于动态具身物理和社会互动的评估标准
  • docker 搭建 mysql 主从
  • 人工智能丨PyTorch 强化学习与自然语言处理
  • 小白如何制作精致 PPT?免费 Office 插件来帮忙
  • 116,【8】 攻防世界 web shrine
  • Anaconda 下个人环境的快速安装指南:支持 GPU 运算的 PyTorch 环境
  • 清除el-table选中状态 clearSelection
  • 春晚「宇树科技」人形机器人H1技术浅析!
  • M系列/Mac安装配置Node.js全栈开发环境(nvm+npm+yarn)
  • 脚本批量重启openstack虚拟机并加上启动编号、脚本批量验证openstack虚拟机状态并加上编号
  • Vuex 解析:从 Vue 2 到 Vue 3 的演变与最佳实践
  • Gemini 2.0 全面开放,AI 进入新纪元!
  • deepseek r1 完全本地部署实战教程
  • [paddle] 矩阵的分解
  • Python——Unicode 编码 或 解码 工具(GUI打包版)
  • 禅道社区版项目管理软件部署(记录篇)
  • System类
  • 联想拯救者开机进入bios
  • 2025年前端面试准备html篇
  • @DeclareParents
  • 如何借助DeepSeek、ChatGPT等AI模型构建自己的量化交易策略?