javaSE

Java的基本数据类型

Java 中有 8 种基本数据类型,分别为:

  • 6 种数字类型:

    • 4 种整数型: byte 、 short 、 int 、 long

      大小(字节):1、2、4、8

    • 2 种浮点型: float 、 double

      大小(字节):4、8

  • 1 种字符类型: char

    大小(字节):2

  • 1 种布尔型: boolean

    大小(字节):1

这八种基本类型都有对应的包装类分别为: Byte 、 Short 、Integer 、 Long 、 Float 、 Double 、 Character 、 Boolean


为什么用BigDecimal不用double/double计算出现 什么问题

  • double会出现精度丢失的问题

    计算机无法精确地表示小数, 所以做浮点数计算时会出现精度 丢失问题.

  • BigDecimal底层是用字符串存储数字, 运算也是用字符串做加减乘除计算的, 所以它能做到精确计算

    所以一般牵扯到金钱等精确计算,都使用Decimal。


基本类型和包装类型的区别

  • 包装类型不赋值就是 null ,而基本类型有默认值且不是 null。
  • 包装类型可用于泛型,而基本类型不可以。
  • 基本数据类型存放在栈中。包装类型属于对象类型,几乎所有对象实例都存在于堆中。
  • 相比于对象类型, 基本数据类型占用的空间非常小。

自动装箱与拆箱

  • 装箱:将基本类型用它们对应的引用类型包装起来;调用了包装类的valueOf()方法
  • 拆箱:将包装类型转换为基本数据类型;调用了 xxxValue()方法

Integer的缓存问题

java 复制代码
Integer i1 = 100;  
Integer i2 = 100;  
System.out.println(i1 == i2);  // true
Integer i3 = 1000;  
Integer i4 = 1000;  
System.out.println(i3 == i4);  // false

为什么出现上面这种奇怪的现象?

  • Java的Integer类内部实现了一个静态缓存池,用于存储特定范围内的整数值对应的Integer对象。
  • 默认情况下,这个范围是-128至127。当创建一个在这个范围内 的整数对象时,并不会每次都生成新的对象实例,而是复用缓存中的现有对象,会直接从内存中取出,不需要新建一个对象。

所以, 在对比是一定要用equals().


深拷贝和浅拷贝区别?什么是引用拷贝

  • 浅拷贝:浅拷贝会在堆上创建一个新的对象(区别于引用拷贝的一点),不过,如果原对象内部的属性是引用类型的话,浅拷贝会直接复制内部对象的引用地址,也就是说拷贝对象和原对象共用同一个内部对象。
  • 深拷贝 :深拷贝会完全复制整个对象,包括这个对象所包含的内部对象。
  • 引用拷贝: 引用拷贝就是两个不同的引用指向同一个对象。

== 和 equals() 的区别

== 对于基本类型和引用类型的作用效果是不同的:

  • 对于基本数据类型来说,== 比较的是值
  • 对于引用数据类型来说,== 比较的是对象的内存地址

equals() 方法存在两种使用情况:

  • 类没有重写 equals() 方法 :通过equals()比较该类的两个对象时,等价于通过"=="比较这两个对象,使用的默认是 Object 类equals()方法。
  • 类重写了 equals() 方法 :一般我们都重写 equals()方法来比较两个对象中的属性是否相等;若它们的属性相等,则返回 true(即,认为这两个对象相等)。

String 中的 equals 方法是被重写过的,因为 Object 的 equals 方法是比较的对象的内存地址,而 String 的 equals 方法比较的 是对象的值。


hashCode() 有什么用

hashCode() 的作用是获取哈希值。这个哈希值的作用是确定该对象在哈希表中的索引位置 (可以快速找到所需要的对象)

Java用hashcode()和equals()判断是否为同一个对象

  • 如果两个对象的hashCode 值相等,那这两个对象不一定相等 (哈希碰撞)。

  • 如果两个对象的hashCode 值相等并且equals()方法也返回 true,我们才认为这两个对象相等

  • 如果两个对象的hashCode 值不相等,我们就可以直接认为这两个对象不相等。


重写equals为什么要重写hashcode

因为java判断两个对象是否是相等的, 需要先比较hashcode是否一 致, 如果hashcode不一致那么就认为不相等.

如果没有重写hashcode, 那么两个相等的对象由于hashcode不相等, 就会被认为是不相等的. 但是按照重写的equals规则, 他们应该是相 等的.

在集合中, 如set集合去重中就会出现, 两个相等的对象放到set中都可以存在的怪象.


抽象类和接口的区别

  • 抽象类和接口都不能直接实例化。如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。
  • 抽象类要被子类继承,接口要被类实现。
  • 接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现。
  • 接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
  • 抽象方法要被实现,所以不能是静态的,也不能是私有的
  • 抽象类是对事物的抽象,即对类抽象;接口是对行为抽象,即局部抽象。抽象类对整体形为进行抽象,包括形为和属性。接口只对行为进行抽象。
  • 抽象类是多个子类的父类,定义了子类大概的共性的东西,是一 种模板式设计;接口是一种行为规范,是一种辐射式设计。

面向对象的三大特征

  • 封装
    • 为了提高代码的安全性,隐藏对象的内部细节,封装将对象的内部状态(字段、属性)隐藏起来,并通过定义公共的方法(接口)来操作对象
    • 外部代码只需要知道如何使⽤这些⽅法而无需了解内部实现
  • 继承
    • 允许一个类(子类)继承另⼀个类(父类)的属性和⽅法的 机制
    • 子类可以重用父类的代码,并且可以通过添加新的方法或修 改(重写)已有的方法来扩展或改进功能
    • 提高了代码的可重用性和可扩展性
  • 多态
    • 多态是指相同的操作或方法法可以在不同的对象上产生不同的行为,通过方法的重载和重写实现
    • 多态允许以一致的方式式处理不同类型的对象,提高了代码的灵活性

面向对象和面向过程的区别

  • 面向过程: 直接将解决问题的步骤分析出来,然后用函数把步骤一步 一步实现,然后再依次调用就可以了. 面向过程思想偏向于我们做一 件事的流程,首先做什么,其次做什么,最后做什么。

  • 面向对象: 将构成问题的事物,分解成若干个对象,建立对象的目的 不是为了完成一个步骤,而是为了描述某个事物在解决问题过程中 的行为。 需要完成什么事情, 直接让某个对象来干即可.


类和对象

  • 类: 像是一个抽象的设计图/模板. 类往往保存一类事物的共性(属性), 共有行为.
  • 对象: 是通过这个设计图/模板创造出来具体实例. 实例往往是共性个性化的表现.

说⼀说你对多态的理解

  • 子类其实是⼀种特殊的父类,因此Java允许把⼀个子类对象直接赋给⼀个父类引用变量,无须任何类型转换, 或者被称为向上转 型,向上转型由系统自动完成。
  • 当把⼀个子类对象直接赋给父类引用变量时,例如 FatherObj o = new SonObj() , 这个 编译时类型是 FatherObj,而运行时 类型是 SonObj,当运行时调其方法时,其方法行为实际是子类 的行为, 也就是SonObj的行为.
  • 这就可能出现:相同类型的变量、调用同一个方法时出现不同的行为,这就是所谓的多态

方法的重载和重写有什么区别

  • 重载方法法的重载指的是在同⼀个类中,方法名相同但参数列表不同
  • 重写是在子类中重新定义⽗类中已有的方法,方法名和参数列表必须相同

静态变量和静态方法与非静态有什么区别

静态变量和静态方法是与类本身关联的,而不是与类对象关联. 它们在内存中只存在一份,可以被类的所有实例共享.

换句话说, 静态是属于类的, 是被类所有对象共享的.

静态变量

  • 共享性:所有该类的实例共享同一个静态变量。如果一个实例修改了静态变量的值,其他实例也会看到这个更改。
  • 初始化:静态变量在类被加载时初始化,只会对其进行一次分配内存。
  • 访问方式:静态变量可以直接通过类名访问,也可以通过实例访问,但推荐使用类名访问。

静态方法

  • 共享性:所有该类的实例共享同一个静态方法.
  • 访问方式:静态方法可以直接通过类名调用, 不需要创建对象.
  • 访问静态成员:静态方法可以直接调用其他静态变量和静态方法,但不能直接访问非静态成员. 因为静态没有依赖具体对象.

final的作用

  • 被final修饰的类无法继承
  • 被final修饰的方法无法重写
  • 被final修饰的变量为常量, 无法重新赋值
    • final修饰基本类型变量, 无法修改
    • final修饰引用类型, 这个引用无法指向其他对象, 也就是地址 无法修改, 但是对象属性可修改.

String的不可变性

String类中包含一个数组, 储存数组的每一个字符: private final byte[] value;

  • final数组, 地址不能改变, 导致长度不能改变
  • private, 数组中的内容不能改变

String s1 = new String("abc");这句话创建了几个字符串对象?

会创建 1 或 2 个字符串。

如果字符串常量池中不存在字符串对象"abc"的引用,那么会在堆中创建2个对象

  • 一个是new的String对象
  • 一个是char[]对应的常量池中的数据:"abc"

如果字符串常量池中存在字符串对象"abc"的引用,那么会在堆中创建1个对象, 就是new的String对象


String和StringBuffer和StringBuilder区别

  • String:字符串变量,private final修饰,不可变!
  • StringBuilder:字符串变量(线程不安全,可变) 没有使用 final 和 private 关键字修饰
  • StringBuffer:字符串变量(线程安全,可变) 没有使用 final 和 private 关键字修饰
  • StringBuilder是StringBuffer的简易版,更快!

每次对 String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象。StringBuilder 或 StringBuffer 每次都会对 StringBuilder 或 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。

对于三者使用的总结:

  • 操作少量的数据: 适用 String
  • 单线程做大量字符串拼接操作: 适用 StringBuilder
  • 多线程做大量字符串拼接操作: 适用 StringBuffer

字符串拼接用"+" 还是 StringBuilder

对象引用和"+"的字符串拼接方式,实际上是通过 StringBuilder 调用 append() 方法实现的,拼接完成之后调用 toString() 得到 一个 String 对象 。

不过,在循环内使用"+"进行字符串的拼接的话,存在比较明显的缺陷:编译器不会创建单个 StringBuilder 以复用,会导致创建过多的 StringBuilder 对象。 StringBuilder 对象是在循环内部被创建的,这意味着每循环一次就会创建一个 StringBuilder 对 象。

所以需要把new StringBuilder() 放在循环外部.


字符串常量池的作用了解吗

字符串常量池 是 JVM 为了提升性能和减少内存消耗针对字符串 (String 类)专门开辟的一块区域,主要目的是为了避免字符串的重复创建

开发中使用的字符串很可能有大量的重复, 字符串常量池就可以将重复的字符串只保存一份, 极大地节省了内存.


反射的基本思想

反射机制是在运行时,能够动态获取类的所有属性和方法;动态调用对象任意方法, 动态的创建对象

但是反射需要在运行时动态解析类、方法、字段的元数据信息, 性能较差

反射特性:

  • 运行时类信息访问:反射机制允许程序在运行时获取类的完整结 构信息,包括类名、包名、父类、实现 的接口、构造函数、方法和字段等。
  • 动态对象创建:可以使用反射API动态地创建对象实例,即使在 编译时不知道具体的类名。这是通过 Class类的newlnstance()方法或Constructor对象的 newlnstance()方法实现的。
  • 动态方法调用:可以在运行时动态地调用对象的方法,包括私有 方法。这通过Method类的invoke()方法 实现,允许你传入对象实例和参数值来执行方法。
  • 访问和修改字段值:反射还允许程序在运行时访问和修改对象的 字段值,即使是私有的。这是通过 Field类的get()和set()方法完成的。

你平时什么时候会用到反射

  • 当要从配置文件中读配置创建类对象时需要使用反射
    • 配置文件配置某个类的全类名, 然后就需要读配置, 然后反射 创建对象
  • 使用工厂模式时, 往往也需要根据全类名来获取对象, 也会使用反 射创建对象.
  • 当开发注解时, 往往需要反射来获取某个类/字段的注解
  • 当使用spring, mybatis时, 这些框架底层会大量使用反射
    • Spring 的IoC机制:会通过反射实例化 Bean、注入依赖
    • Spring的AOP用到了动态代理, 也是大量使用反射
    • MyBatis 的 Mapper 接口动态代理:反射生成接口的代理对象,执行 SQL 映射方法

相关推荐
Swift社区2 小时前
Java 实战 -Error和Exception有什么区别?
java·开发语言
曹轲恒2 小时前
SpringBoot整合SpringMVC(下)
java·spring boot·spring
季明洵2 小时前
备考蓝桥杯第四天
java·数据结构·算法·leetcode·链表·哈希算法
空空kkk2 小时前
spring boot——配置文件
java·数据库·spring boot
what丶k2 小时前
Spring Boot 3 注解大全(附实战用法)
java·spring boot·后端
gAlAxy...2 小时前
Thymeleaf 从入门到精通:Spring Boot 模板引擎实战指南
java·spring boot·后端
焦糖玛奇朵婷2 小时前
就医陪诊小程序|从软件开发视角看实用度✨
java·大数据·jvm·算法·小程序
Yvonne爱编码2 小时前
深入剖析 Java 中的深拷贝与浅拷贝:原理、实现与最佳实践
java·开发语言
是三好2 小时前
Spring全家桶
java·后端·spring