Java-易错知识点汇总

  1. Math.round(11.5)等于多少?Math.round(-11.5)等于多少?

    : Math.round(-11.5)返回值是-11

    ​ Math.round(11.5)返回值是12 四舍五入 的原理是在参数上加0.5然后向下取整

  2. switch 是否能作用在byte 上,是否能作用在long 上,是否能作用在String上?

    :在Java 5以前,switch(expr)中,expr只能是byte、short、char、int。

    从Java 5开始,Java中引入了枚举类型,expr也可以是enum类型,从Java 7开始,expr还可以是字符串(String),但是长整型(long)在目前所有的版本中都是不可以的。

  3. 抽象类(abstract class)和接口(interface)有什么异同?

    • 抽象类和接口都不能够实例化,但可以定义抽象类和接口类型的引用。
    • 一个类如果继承了某个抽象类或者实现了某个接口都需要对其中的抽象方法全部进行实现,否则该类仍然需要被声明为抽象类。
    • 接口比抽象类更加抽象,因为抽象类中可以定义构造器,可以有抽象方法和具体方法,而接口中不能定义构造器而且其中的方法全部都是抽象方法。
    • 抽象类中的成员可以是private、默认、protected、public的,而接口中的成员全都是public的。抽象类中可以定义成员变量,而接口中定义的成员变量实际上都是常量。
    • 有抽象方法的类必须被声明为抽象类,而抽象类未必要有抽象方法。
  1. 抽象的(abstract)方法是否可同时是静态的(static),是否可同时是本地方法(native),是否可同时被synchronized修饰?
    :都不能。抽象方法需要子类重写,而静态的方法是无法被重写的,因此二者是矛盾的。本地方法是由本地代码(如C代码)实现的方法,而抽象方法是没有实现的,也是矛盾的。synchronized和方法的实现细节有关,抽象方法不涉及实现细节,因此也是相互矛盾的。
  1. 如何实现对象克隆?
    :有两种方式:
     1). 实现Cloneable接口并重写Object类中的clone()方法;
     2). 实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆
  1. String s = new String(“xyz”);创建了几个字符串对象?
    :两个对象,一个是静态区的”xyz”,一个是用new创建在堆上的对象。
  1. Java的四种引用,强弱软虚

    :

    • 强引用

      强引用是平常中使用最多的引用,强引用在程序内存不足(OOM)的时候也不会被回收,使用方式

    1
    String str = new String("str");
    • 软引用

      软引用在程序内存不足时会被回收,使用方式

    1
    2
    3
    // 注意:wrf这个引用也是强引用,它是指向SoftReference这个对象的,
    // 这里的软引用指的是指向new String("str")的引用,也就是SoftReference类中T
    SoftReference<String> wrf = new SoftReference<String>(new String("str"));
    • 弱引用
      弱引用就是只要JVM垃圾回收器发现了它,就会将之回收,使用方式:
    1
    WeakReference<String> wrf = new WeakReference<String>(str);
    • 虚引用
      虚引用的回收机制跟弱引用差不多,但是它被回收之前,会被放入 ReferenceQueue 中。注意,其它引用是被JVM回收后才被传入 ReferenceQueue 中的。由于这个机制,所以虚引用大多被用于引用销毁前的处理工作。还有就是,虚引用创建的时候,必须带有 ReferenceQueue ,使用例子
    1
    PhantomReference<String> prf = new PhantomReference<String>(new String("str"), new ReferenceQueue<>());
  1. Excption与Error包结构
    Java可抛出(Throwable)的结构分为三种类型:被检查的异常(CheckedException),运行时异常(RuntimeException),错误(Error)

    运行时异常
    定义:RuntimeException及其子类都被称为运行时异常。
    特点:Java编译器不会检查它。也就是说,当程序中可能出现这类异常时,倘若既”没有通过throws声明抛出它”,也”没有用try-catch语句捕获它”,还是会编译通过

    例如,

    除数为零时产生的ArithmeticException异常,

    数组越界时产生的IndexOutOfBoundsException异常,

    fail-fast机制产生的ConcurrentModificationException异常(java.util包下面的所有的集合类都是快速失败的,“快速失败”也就是fail-fast,它是Java集合的一种错误检测机制。当多个线程对集合进行结构上的改变的操作时,有可能会产生fail-fast机制。记住是有可能,而不是一定。例如:假设存在两个线程(线程1、线程2),线程1通过Iterator在遍历集合A中的元素,在某个时候线程2修改了集合A的结构(是结构上面的修改,而不是简单的修改集合元素的内容),那么这个时候程序就会抛出ConcurrentModificationException 异常,从而产生fail-fast机制,这个错叫并发修改异常.Fail-safe,java.util.concurrent包下面的所有的类都是安全失败的,在遍历过程中,如果已经遍历的数组上的内容变化了,迭代器不会抛出ConcurrentModificationException异常。如果未遍历的数组上的内容发生了变化,则有可能反映到迭代过程中。这就是ConcurrentHashMap迭代器弱一致的表现。ConcurrentHashMap的弱一致性主要是为了提升效率,是一致性与效率之间的一种权衡。要成为强一致性,就得到处使用锁,甚至是全局锁,这就与Hashtable和同步的HashMap一样了。)等,都属于运行时异常。

    被检查异常

    定义:Exception类本身,以及Exception的子类中除了”运行时异常”之外的其它子类都属于被检查异常。
    特点 : Java编译器会检查它。 此类异常,要么通过throws进行声明抛出,要么通过try-catch进行捕获处理,否则不能通过编译。例如,CloneNotSupportedException就属于被检查异常。当通过clone()接口去克隆一个对象,而该对象对应的类没有实现Cloneable接口,就会抛出
    CloneNotSupportedException异常。被检查异常通常都是可以恢复的。
    如:
    IOException
    FileNotFoundException
    SQLException
    被检查的异常适用于那些不是因程序引起的错误情况,比如:读取文件时文件不存在引发的
    FileNotFoundException 。然而,不被检查的异常通常都是由于糟糕的编程引起的,比如:在对象引用时没有确保对象非空而引起的 NullPointerException

    错误

    定义 : Error类及其子类。
    特点 : 和运行时异常一样,编译器也不会对错误进行检查。
    当资源不足、约束失败、或是其它程序无法继续运行的条件发生时,就产生错误。程序本身无法修复这些错误的。例如,VirtualMachineError就属于错误。出现这种错误会导致程序终止运行。
    OutOfMemoryError、ThreadDeath。
    Java虚拟机规范规定JVM的内存分为了好几块,比如堆,栈,程序计数器,方法区等

  1. Java 序列化中如果有些字段不想进行序列化,怎么办?
    对于不想进行序列化的变量,使用 transient 关键字修饰。
    transient 关键字的作用是:阻止实例中那些用此关键字修饰的的变量序列化;当对象被反序列化时,被 transient 修饰的变量值不会被持久化和恢复。transient 只能修饰变量,不能修饰类和方法

空串与null

String变量还可以存放一个空值,名为null,表示目前没有任何对象与该变量关联

if(str==null)

要检查一个字符串既不是null也不是空串,这种情况下就需要使用一下条件

if(str!=null&&str.length()!=0)