Java基础篇(二)

从本篇起,Java基础篇的整理主要偏向于面试题

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

  • 面向过程性能高,因为类调用时需要实例化,开销比较大,比较消耗资源
  • 面向过程没有面向对象易维护、易复用、易扩展(封装、继承、多态)

JVM

  • Java虚拟机(JVM)是运行 Java 字节码的虚拟机。JVM有针对不同系统的特定实现(Windows,Linux,macOS),目的是使用相同的字节码,它们都会给出相同的结果。字节码和不同系统的 JVM 实现是 Java 语言“一次编译,随处可以运行”的关键所在。

构造器Constructor 是否可被 override?

  • 继承的时候我们就知道父类的私有属性和构造方法并不能被继承,所以 Constructor 也就不能被 override(重写),但是可以 overload(重载),所以你可以看到一个类中有多个构造函数的情况。

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

  • 封装:封装把一个对象的属性私有化,同时提供一些可以被外界访问的属性的方法,如果属性不想被外界访问,我们大可不必提供方法给外界访问。但是如果一个类没有提供给外界访问的方法,那么这个类也没有什么意义了。

String StringBuffer 和 StringBuilder 的区别是什么? String 为什么是不可变的?

  • String类中:private final char value[] --->不可变
  • StringBuilder 与 StringBuffer 的构造方法都是调用父类构造方法也就是 AbstractStringBuilder 实现
  • StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁(synchronized),所以是线程安全的。StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的

接口和抽象类区别

  • 接口的方法默认是 public,所有方法在接口中不能有实现(Java 8 开始接口方法可以有默认实现),而抽象类可以有非抽象的方法。
  • 接口中除了static、final变量,不能有其他变量,而抽象类中则不一定。
  • 一个类可以实现多个接口,但只能实现一个抽象类。接口自己本身可以通过extends关键字扩展多个接口。
  • 在JDK8中,接口也可以定义静态方法,可以直接用接口名调用。实现类和实现是不可以调用的。如果同时实现两个接口,接口中定义了一样的默认方法,则必须重写,不然会报错。

对象实体和对象引用有何区别?

  • new创建对象实例(对象实例在堆内存中),对象引用指向对象实例(对象引用存放在栈内存中)。一个对象引用可以指向0个或1个对象(一根绳子可以不系气球,也可以系一个气球);一个对象可以有n个引用指向它(可以用n条绳子系住一个气球)。

实例方法和静态方法有何不同?

  • 浅层次:在外部调用静态方法时,可以使用"类名.方法名"的方式也可以使用"对象名.方法名"的方式。而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象。(静态方法的调用不依赖于对象)
  • JVM深层次:类的静态方法,静态变量是在类装载的时候装载的,这时候还没有产生对象**。静态变量 存放在 Java 内存区域的方法区**
  • static关键字使用场景
    1. 修饰成员变量和成员方法: 被 static 修饰的成员属于类,不属于单个这个类的某个对象,被类中所有对象共享,可以并且建议通过类名调用。被static 声明的成员变量属于静态成员变量,静态变量 存放在 Java 内存区域的方法区。调用格式:类名.静态变量名 类名.静态方法名()
    2. 静态代码块: 静态代码块定义在类中方法外, 静态代码块在非静态代码块之前执行(静态代码块—>非静态代码块—>构造方法)。 该类不管创建多少对象,静态代码块只执行一次.
    3. 静态内部类(static修饰类的话只能修饰内部类): 静态内部类与非静态内部类之间存在一个最大的区别: 非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外围类,但是静态内部类却没有。没有这个引用就意味着:1. 它的创建是不需要依赖外围类的创建。2. 它不能使用任何外围类的非static成员变量和方法。
    4. 静态导包(用来导入类中的静态资源,1.5之后的新特性): 格式为:import static 这两个关键字连用可以指定导入某个类中的指定静态资源,并且不需要使用类名调用类中静态成员,可以直接使用类中静态成员变量和成员方法。

final关键字

  • 可作用在变量、方法、类

  • final作用在基本数据类型上:数值一旦初始化便不能随意更改;final作用在引用型变量:初始化之后不能再指向其他的对象

  • final作用在类上-->该类不能被继承,所有的成员方法默认为final

  • final作用在方法上:

    • 把方法锁定,防止任何继承类修改它的含义
  • 类中的private修饰的方法默认添加有final关键字

Java中异常

层次

image-20191217165252832
  • Error(错误):是程序无法处理的错误,表示运行应用程序中较严重问题。大多数错误与代码编写者执行的操作无关,而表示代码运行时 JVM(Java 虚拟机)出现的问题。
  • Exception(异常):是程序本身可以处理的异常。Exception 类有一个重要的子类 RuntimeException。RuntimeException 异常由Java虚拟机抛出。NullPointerException(要访问的变量没有引用任何对象时,抛出该异常)、ArithmeticException(算术运算异常,一个整数除以0时,抛出该异常)和 ArrayIndexOutOfBoundsException (下标越界异常)。
  • 异常和错误的区别:异常能被程序本身处理,错误是无法处理。

try/catch/fianlly

  • try 块: 用于捕获异常。其后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块。
  • catch 块: 用于处理try捕获到的异常。
  • finally 块: 无论是否捕获或处理异常,finally块里的语句都会被执行。当在try块或catch块中遇到return 语句时,finally语句块将在方法返回之前被执行。
  • finally语句块不会被执行的情况:
    1. 在finally语句块第一行发生了异常。 因为在其他行,finally块还是会得到执行
    2. 在前面的代码中用了System.exit(int)已退出程序。 exit是带参函数 ;若该语句在异常语句之后,finally会执行
    3. 程序所在的线程死亡。
    4. 关闭CPU。

深拷贝/浅拷贝

浅拷贝:对基本数据类型进行值传递,引用类型的属性复制,复制栈中的变量 和 变量指向堆内存中的对象的指针,不复制堆内存中的对象。

image-20191217170403217

深拷贝:对基本数据类型进行值传递,引用类型的属性复制,复制栈中的变量 和 变量指向堆内存中的对象的指针和堆内存中的对象。(在堆中创建了新的对象)

image-20191217170540653

反射

对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。--->反射就是把java类中的各种成分映射成一个个的Java对象

image-20191217172633390
  • 反射优势:运行期类型的判断,动态加载类,提高代码灵活度。

应用:

  • JDBC 连接数据库时使用 Class.forName()通过反射加载数据库的驱动程序
  • Spring XML配置方法进行装在Bean
赞赏