JAVA基础知识回顾

1.JVM

Java虚拟机(JVM)是运行Java字节码的(.class)。-->高效;可移植

Java程序从源代码到运行一般有以下3步:

.java文件(源代码)  -->(JDK中的javac编译)  -->  .class文件(JVM可理解的Java字节)  -->  (JVM)  -->机器可执行的二进制机器码

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

 

2.什么是Java程序的主类 应用程序和小程序的主类有何不同?

一个程序中可以有多个类,但只能有一个类是主类。在Java应用程序中,这个主类是指包含main()方法的类。

 

3.构造器Constructor是否可以被override?

Constructor不能被override(重写),但是可以overload(重载),所以可以看到一个类中有多个构造函数的情况。

 

4.重载和重写的区别

重载

发生在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可以不同

重写

重写是子类对父类的允许访问的方法的实现过程进行重新编写,发生在子类中,方法名、参数列表必须相同,返回值范围小于等于父类抛出的异常范围小于等于父类,访问修饰符范围大于等于父类。另外,如果父类方法访问修饰符为private则子类就不能重写该方法。也就是说方法提供的行为改变,而方法的外貌并没有改变

 

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

String类中使用final关键字修饰字符数组来保存字符串,private final char value [],所以String对象是不可变的。Java9之后改用byte存储

StringBuilder和StringBuffer都继承自AbstractStringBuilder类, 在AbstractStringBuilder中也是使用字符数组保存字符串

char[] value但是没有用final关键字修饰,所以这两种对象都是可变的。两者的构造方法都是调用父类构造方法实现的

 

线程安全性:String和StringBuffer是线程安全的

StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。

 

性能:

每次对String类型进行改变的时候,都会生成一个新的String对象,然后将指针指向新的String对象。StringBuffer每次都会对StringBuffer对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用StringBuilder相比使用StringBuffer仅能获得10%~15%左右的性能提升,但却要冒多线程不安全的风险

 

String 被声明为 final,因此它不可被继承。(Integer 等包装类也不能被继承)

在 Java 8 中,String 内部使用 char 数组存储数据。

在 Java 9 之后,String 类的实现改用 byte 数组存储字符串,同时使用 coder 来标识使用了哪种编码

6.在一个静态方法内调用一个非静态成员为什么是非法的?

由于静态方法可以不通过对象进行调用,因此在静态方法里,不能调用其他非静态变量,也不可以访问非静态变量成员

 

7.自动装箱与拆箱

装箱: 将基本类型用它们对应的引用类型包装起来

拆箱:将包装类型转换为基本数据类型

 

8.在Java中定义一个无参构造方法的作用

Java程序在执行子类的构造方法之前,如果没有用super()来调用父类特定的构造方法,则会调用父类中”没有参数的构造方法“。因此,如果父类中只定义了有参数的构造方法,而在子类的构造方法中又没有用super()来调用父类中特定的构造方法,则编译时将发生错误,因为Java程序在父类中找不到没有参数的构造方法可供执行。解决办法是在父类里加上一个没有参数的构造方法

 

9.接口和抽象类的区别是什么?

接口的方法默认是public,所有方法在接口中不能有实现(Java8开始接口方法可以有默认实现),而抽象类可以有非抽象的方法

接口中除了static、final变量,不能有其他变量,而抽象类中则不一定

一个类可以实现多个接口,但只能实现一个抽象类。接口自己本身可以通过extends关键字扩展多个接口

接口方法默认修饰符是public,抽象方法可以有public、protected和default这些修饰符(抽象方法就是为了被重写所以不能使用private关键字修饰)

从设计层面来说,抽象是对类的抽象,是一种模板设计,而接口是对行为的抽象,是一种行为的规范

 

10.面向对象编程三大特性:封装  继承  多态

封装:封装把一个对象的属性私有化,同时提供一些可以被外界访问的属性的方法

继承:继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。通过使用继承我们能够非常方便地复用以前的代码。

  注意:1.子类拥有父类对象所有的属性和方法(包括私有属性和私有方法),但是父类中的私有属性和方法子类是无法访问,只是拥有。

     2.子类可以拥有自己属性和方法,即子类可以对父类进行扩展

     3.子类可以用自己的方式实现父类的方法

多态:就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量到底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定

在Java中有两种形式可以实现多态:继承(多个子类对同一方法的重写)和接口(实现接口并覆盖接口中同一方法)

 

11.成员变量与局部变量的区别有哪些?

1.从语法形式上看:成员变量是属于类的,而局部变量是在方法中定义的变量或是方法的参数;成员变量可以被public,private,static等修饰符所修饰,而局部变量不能被访问控制修饰符及static所修饰,但是成员变量和局部变量都能被final所修饰

2.从变量在内存中的存储方式来看:如果成员变量是使用static修饰的,那么这个成员变量是属于类的,如果没有使用static修饰,这个成员变量是属于实例的。而对象存在于堆内存,局部变量则存在于栈内存

3.从变量在内存中的生存时间上看:成员变量是对象的一部分,它随着对象的创建而存在,而局部变量随着方法的调用而自动消失

4.成员变量如果没有被赋初值:则会自动以类型的默认值而赋值(一种情况例外:被final修饰的成员变量也必须显式地赋值),而局部变量则不会自动赋值

 

12.创建一个对象用什么运算符?对象实体与对象引用有何不同?

new运算符,new创建对象实例(对象实例在堆内存中),对象引用指向对象实例(对象引用存放在栈内存中)。一个对象引用可以指向0个或1个对象,一个对象可以有n个引用指向它

 

13.什么是方法的返回值?返回值在类的方法里的作用是什么?

方法的返回值是指我们获取到的某个方法体中的代码执行后产生的结果。返回值的作用:接收出结果,使得它可以用于其他的操作

 

14.一个类的构造方法的作用是什么?若一个类没有声明构造方法,该程序能正确执行吗?为什么?

主要作用是完成类对象的初始化工作。可以执行。默认的不带参的构造方法。

 

15.构造方法有那些特性?

1.名字与类名相同

2.没有返回值,但不能用coid声明构造函数

3.生成类的对象时自动执行,无需调用

 

16.静态方法和实例方法有何不同

1.在外部调用静态方法时,可以使用“类名.方法名”的方式,也可以使用“对象名.方法名”的方式。

  静态方法在类加载的时候就存在了,它不依赖于任何实例。所以静态方法必须有实现,也就是说它不能是抽象方法。

  只能访问所属类的静态字段和静态方法,方法中不能有 this 和 super 关键字,因此这两个关键字与具体对象关联。

  静态语句块在类初始化时运行一次。

  非静态内部类依赖于外部类的实例,也就是说需要先创建外部类实例,才能用这个实例去创建非静态内部类。而静态内部类不需要。

  静态内部类不能访问外部类的非静态的变量和方法。

  静态变量和静态语句块优先于实例变量和普通语句块,静态变量和静态语句块的初始化顺序取决于它们在代码中的顺序。

2.静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法,实例方法则无此限制

 

 

17.对象的相等与指向它们的引用相等,两者有什么不同?

对象的相等,比的是内存中存放的内容是否相等。而引用相等,比较的是他们指向的内存地址是否相等

 

18.在调用子类构造方法之前会先调用父类没有参数的构造方法,其目的是?

帮助子类做初始化工作

 

19.==与equals

==:它的作用是判断两个对象的地址是不是相等;基本数据类型==比较的是值,引用数据类型==比较的是内存地址

equals():它的作用也是判断两个对象是否相等

情况1:类没有覆盖equals()方法。则通过equals()比较该类的两个对象时,等价于通过==

情况2:类覆盖了equals()方法。一般都会覆盖equals()方法来比较两个对象的内容是否相等。

注意:

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

当创建String类型的对象时,虚拟机会在常量池中查找有没有已经存在的值和要创建的值相同的对象,如果有就把它赋给当前引用。如果没有就在常量池中重新创建一个String对象

 

20.hashCode与equals

为什么重写equals时必须重写hashCode方法?

hashCode()-->获取哈希码/散列码;它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。hashCode()定义在JDK的Object.java中,这就意味着Java中的任何类都包含有hashCode()函数

散列表存储的是键值对(key-value),特点是:能根据“键”快速的检索出对应的“值”

hashCode()与equals()的相关规定

1.如果两个对象相等,则hashcode一定也是相同的

2.两个对象相等,对两个对象分别调用equals方法都返回true

3.两个对象有相同的hashcode值,它们也不一定是相等的

4.因此,equals方法被覆盖过,则hashCode方法也必须被覆盖

5.hashCode()的默认行为是对堆上的对象产生独特值。如果没有重写hashCode(),则该class的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)

https://www.cnblogs.com/skywang12345/p/3324958.html

 

21.为什么Java中只有值传递?

按值调用表示方法接收的是调用者提供的值,而按引用调用表示方法接收的是调用者提供的变量地址。一个方法可以修改传递引用所对应的变量值,而不能修改传递值调用所对应的变量值。

Java总是采用按值调用,也就是说,方法得到的是所有参数值的一个拷贝,方法不能修改传递给它的任何参数变量的内容

一个方法不能修改一个基本数据类型的参数

一个方法可以改变一个对象参数的状态

一个方法不能让对象参数引用一个新的对象

https://juejin.im/post/5e18879e6fb9a02fc63602e2

 

22.简述线程、程序、进程的基本概念。以及它们之间关系是什么?

 

23.线程有哪些基本状态?

 

 

24.关于final关键字

主要用于三个地方:变量、方法、类

1.对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后编不能再让其指向另一个对象,但被引用的对象本身是可以修改的

2.当用final修饰一个类时,表示这个类不能被继承。final类中的所有成员方法都会被隐式地指定为final方法

3.使用final方法的原因:把方法锁定,以防任何继承类修改它的含义;效率。类中所有的private方法都隐式地指定为final

 

25.Java中的异常处理

所有异常的共同祖先,java.lang包中的Throwable类

Throwable类有两个重要的子类:Exception异常和Error错误

Error:是程序无法处理的错误,表示运行应用程序中存在较严重问题

Exception:RuntimeException

异常能被程序本身处理,错误是无法处理

 

try catch finally

在以下4种特殊情况下,finally块不会被执行:

1.在finally语句第一行发生了异常。在其他行,finally块还是会得到执行

2.在前面的代码中用了System.exit(int)已退出程序。exit是带参函数,若该语句在异常语句之后,finally会执行

3.程序所在线程死亡

4.关闭CPU

当try语句和finally语句中都有return语句时,在方法返回之前,finally语句的内容将被执行,并且finally语句的返回值将会覆盖原始的返回值

 

26.Java序列化中如果有些字段不想进行序列化,怎么办?

对于不想进行序列化的变量,使用transient关键字修饰

transient关键字的作用是:阻止实例中哪些用此关键字修饰的变量序列化;当对象被反序列化时,被transient修饰的变量值不会被持久化和恢复。transient只能修饰变量,不能修饰类和方法

 

27.获取用键盘输入常用的两种方法

Scanner  -->Scanner input = new Scanner(System.in)

BufferedReader

 

28.Java中IO流

BIO、NIO、AIO(事件和回调机制)

 

29.深拷贝/浅拷贝

浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝

深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容。

 

30.

https://gitee.com/SnailClimb/JavaGuide/blob/master/docs/java/basic/final,static,this,super.md

https://gitee.com/SnailClimb/JavaGuide/blob/master/docs/java/basic/Arrays,CollectionsCommonMethods.md

 

31.数据类型

  基本类型:byte 8  char 16 short 16 int 32  float 32 long 64 double 64 boolean

 

32.缓存池

  new Integer(123)与Integer.valueOf(123)的区别:new Integer(123)每次都会新建一个对象  Integer.valueOf(123)会使用缓存池中的对象,多次调用会取得同一个对象的引用。valueOf() 方法的实现比较简单,就是先判断值是否在缓存池中,如果在的话就直接返回缓存池的内容。在 Java 8 中,Integer 缓存池的大小默认为 -128~127。编译器会在自动装箱过程调用 valueOf() 方法,因此多个值相同且值在缓存池范围内的 Integer 实例使用自动装箱来创建,那么就会引用相同的对象。

posted @ 2020-04-09 23:30  LinBupt  阅读(246)  评论(0编辑  收藏  举报