【Java常见问题】(三)基础知识

93 阅读4分钟

之前在专栏处写过(一)基础知识和(二)volatile关键字,这篇文章又是一锅Java基础知识大杂烩,不知道取什么名字好,只好继续叫“基础知识”了。

什么是反射?

指的是Java中动态获取类或对象的属性及方法以完成功能调用的特性

讲讲Lambda表达式?

函数式编程,可以结合实际的代码例子讲讲它的用法。

多态的实现机制

这是类中的方法的概念。

有override和overload两种实现机制。

这两者有什么区别吗?

结合实际代码,override应用于子类重写父类方法;overload指的是一个类中有多个同名方法,但参数不同。

abstract class和interface的异同?

同:都不用给出具体实现

异:

  • 表现上:class用extends,interface用implements
  • 形式上:抽象类可以包含具体数据及方法;接口必须要遵循统一规范,是没有具体内容的
  • 实现上:一个类只能继承一个抽象类,但可以实现多个接口
  • 功能上:抽象类是is-a,接口是has-a

其他理解:

  • 接口可看作是特殊形式的抽象类
  • 抽象类多用于同类事物中,接口多用于不同类之间

Java的基本数据类型?

  • int
  • long
  • short
  • float
  • double
  • char
  • boolean
  • byte

  • Java还提供了对这些原始数据类型的包装类,如Integer等。原始数据类型按值传递,包装类按引用传递
  • 包装类以及String都是不可变类

那为什么s="xx",s+="xxx"再打印s,s会改变呢?

因为新开了一块内存空间,值为"xxxxx",而s指向了它,而不是直接在原来的内存空间上修改扩充。

如何构造不可变类?它的优缺点是什么?

  • 用private修饰成员变量(防止外部修改)
  • 类中不提供修改成员变量的方法(如setXx)
  • 类不会被子类重写
  • 如有必要,重写equals()和hashCode()方法

优点:线程安全、节省内存

缺点:不可变对象不适应变化,如果有变化,可能会有无法预料的问题

==与equals的区别是什么?

  • ==: 用于比较两个变量的值是否相等,也就是对应内存中存储的数值是否相等,

对于基本类型,它比较的是值,对于引用类型,它比较的是引用。

  • equals:Object类中的equals方法是直接使用==,所以默认情况下它和==一样比较引用;重写后可用来比较对象内容(比如String的equals)

举个例子:

String s1=new String("hello");
String s2=new String("hello");

这两个对象的内存首地址不同,因此存储的数值不同,用==就会显示false;但是对象的内容都是“hello”,所以用equals会显示true

String、StringBuffer、StringBuilder的区别是什么?

  • String是不可变类,StringBuffer、StringBuilder是可变类。
  • StringBuffer和StringBuilder类似,都是字符串缓冲区,但Buffer是线程安全的,效率较低;Builder不线程安全,运行效率更快。

finally中的代码何时被执行?

首先得知道一个概念,finally块中的代码表示最终一定会被执行。

那为什么会有这样一个问题呢?应该是因为有时在前面的代码块中出现了return,所以要分清是在这些return前执行还是之后。

结论就是:finally中的代码是在return前执行的,并且如果finally中有return的话,会覆盖掉别处的return。

finally中的代码最终真的一定会被执行吗?

如果要特别强调这个“一定”的话,那这种说法就是不对的。因为本来这就是异常处理的保证机制,

  • 如果在try之前的代码就已经抛出异常了,自然不会执行最后的finally;
  • 另外,任何程序如果碰到强制退出(exit(0)),也是不会再执行后面的程序了。

i++是线程安全的吗?

实际上,i++在更底层会涉及三步操作(读取-赋值-写回),它不是原子操作,在并发执行时不能保证线程安全。

如果要保证线程安全,可以考虑如下几种机制:

  • 使用原子变量,如Java中的AtomicInteger
  • 使用synchronized关键字
  • 使用锁