Java基础(一)

87 阅读8分钟

作为后端开发人员,Java是我们工作中最熟悉的。今天就回过头来,梳理一下Java基础知识点和语法,通过面试题的形式,扎实Java基础知识。

Java基础总结

问:Java是面向对象语言,那面向对象的特征有哪些?

答:Java是一门面向对象的编程语言,因此具有以下三个特征:

  1. 封装性(Encapsulation):封装是指将对象的属性和行为作为一个整体,对外界隐藏对象的具体实现细节,只提供公共的访问方式。Java中通过访问修饰符(public、private、protected)来实现封装。
  2. 继承性(Inheritance):继承是指在一个已有类的基础上,创建一个新的类,新类具有已有类的所有属性和方法,并且可以新增或修改自己的属性和方法。Java中通过关键字“extends”来实现继承。
  3. 多态性(Polymorphism):多态是指同一个方法在不同情况下有不同的表现形式,即一个方法可以有多种不同的实现方式。Java中通过方法的重载和重写来实现多态。

问:Java的访问修饰符怎么实现封装的?

答:Java 支持 4 种不同的访问权限。分别是private、default、protected、public

  • private : 在同一类内可见。
  • default : 在同一包内都可见。
  • protected : 对同一包内的类和所有子类可见。
  • public : 对所有类可见。

总结下来就是,访问权限从小到大为private、default、protected、public

只有类内可见只有包内可见包内和所有子类可见所有类可见

问:Java 中final和static修饰符有什么作用?

答:Java中的final和static修饰符有以下作用:

  1. final修饰符:final修饰符用来修饰类、方法和变量

    • 如果一个类被final修饰,那么它不能被继承;
    • 如果一个方法被final修饰,那么它不能被重写;
    • 如果一个变量被final修饰,那么它的值不能被修改。
  2. static修饰符:static修饰符用来修饰内部类、方法、成员变量、代码块

    • static修饰的类被称为静态类,即类的实例化不需要创建对象;

    • static修饰的方法被称为静态方法,即它可以直接通过类名来调用,而不需要创建对象。

    • static修饰的成员变量标明归某个类所有,它不依赖于类的特定实例,被类的所有实例共享。

    • static修饰的程序代码块表示静态代码块,当Java虚拟机加载类时,就会执行该代码块;

问:那多态性的实现中,重载和重写有什么区别?

答:重写和重载是两个不同的概念

  • 重载是指在一个类中定义多个同名的方法,但这些方法的参数列表必须不同。重载方法的作用是为了提供不同的功能,以适应不同的输入参数。重载方法的定义必须在类的内部,使用相同的方法名且不能使用相同的参数列表。
  • 重写是指在一个子类中重新定义一个父类中已经存在的方法。重写的目的是为了改变父类方法的行为,以适应子类的特定需求。重写方法的定义必须与父类中的方法具有相同的方法名称、参数列表和返回类型,而且必须在子类中进行定义。

问:那接口和抽象类有什么共同点和区别?

答:Java接口和抽象类都是Java中的一种抽象概念,它们有以下共同点和区别:

共同点:

  • 都是用于抽象出类的行为和属性,以便其他类可以继承或实现它们。
  • 不能被直接实例化,而是需要被子类继承或实现。
  • 都可以包含抽象方法,这些方法没有实现,而是需要在子类中被具体实现

区别:

  • 抽象类可以包含非抽象方法和属性,而接口只能包含抽象方法和常量。接口中只能定义常量,即使用 public static final 修饰的变量,抽象类可以定义普通变量。
  • 子类只能继承一个抽象类,但可以实现多个接口。
  • 接口只能定义public方法,而抽象类可以定义public、protected、private等修饰符的方法。
  • 接口的实现类必须实现接口中的所有抽象方法,而抽象类的子类可以选择性地实现抽象类中的抽象方法。
  • 抽象类的目的是为了共享代码和行为,而接口的目的是为了定义类应该具有的行为,以便其他类可以实现它们。

总之,Java接口和抽象类有很多共同点,但它们的用途和实现方式有所不同。接口主要用于定义规范来限制类的行为,而抽象类主要用于共享代码,并不对类的行为进行限制。

问:Java 中的几种基本数据类型了解么?分别占多少字节

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

  • 6 种数字类型:
    • 4 种整数型:byteshortintlong
    • 2 种浮点型:floatdouble
  • 1 种字符类型:char
  • 1 种布尔型:boolean

数据类型.png

问:缓存池技术了解过吗?

答:缓存池是 Java 5 中引入的一个有助于节省内存、提高性能的特性。

当创建Integer对象时,不使用new Integer(int i)语句,大小在-128~127之间,对象存放在Integer常量池中。

例如:Integer a = 10;

调用的是Integer.valueOf()方法,不会新建对象,而是从缓存池中获取对象。

缓存池.png

如果常量值超过这个范围,就会从堆中创建对象,而不再从缓存池中取。

问:基本类型和包装类型的区别?

答:除了定义一些常量和局部变量之外,我们在其他地方比如方法参数、对象属性中很少会使用基本类型来定义变量。区别有以下几点:

  1. 基本类型是Java中的原始数据类型,包括byte、short、int、long、float、double、char和boolean。它们直接存储在内存中,不需要进行装箱操作。
  2. 包装类型是Java中的引用数据类型,它们分别对应于基本类型,例如Integer、Long、Float、Double、Character和Boolean。它们需要进行装箱操作,将基本类型转换为包装类型,才能存储在内存中。
  3. 基本类型的比较运算符(如==)直接比较的是数据的值,而包装类型的比较运算符(如equals)比较的是对象的引用。

什么是自动拆装箱?

  • 装箱:将基本类型用它们对应的引用类型包装起来;
  • 拆箱:将包装类型转换为基本数据类型;

装箱其实就是调用了包装类的valueOf()方法,拆箱其实就是调用了 xxxValue()方法。

问:那== 和 equals() 有什么区别?

答:在Java中,== 和 equals() 都可以用来比较两个对象的值,但它们的用法和实现方式有所不同:

  1. == 是用来比较两个对象的引用是否相等,即判断两个对象是否指向同一个内存地址,也就是说,它比较的是两个对象是否是同一个对象。如果两个对象的引用相等,则返回true;否则返回false。
  2. equals() 是用来比较两个对象的值是否相等,也就是说,它比较的是两个对象所包含的数据是否相同。如果两个对象的值相等,则 equals() 返回true;否则返回false。

需要注意的是,如果两个对象的类型不同,那么它们的equals() 方法默认是比较它们的引用是否相等,即 == 的作用。如果需要比较两个对象的属性值是否相等,那么需要重写equals() 方法,并在其中比较它们的属性值。

问:重写 equals 时为什么一定要重写 hashCode?

答:因为Java中的哈希表(HashMap)等数据结构是基于哈希值来实现的。如果两个对象的哈希值不同,那么它们将被存储在不同的哈希表中,即使它们的属性值相等。

为了避免这种情况,Java规定如果重写了equals() 方法,那么一定要重写hashCode() 方法,并保证它们的实现方式一致。具体来说,如果两个对象的属性值相等,那么它们的哈希值也应该相等。这样,即使两个对象的属性值相等,但它们的引用不同,它们也将被视为不同的对象,从而避免了哈希表中出现重复的键值对。

未完待续......