Java核心基础学习(一)--- 2019年1月

1、对比Exception和Error,运行时异常与一般异常

  Exception 和 Error 都继承了 Throwable 类,在 Java 中只有 Throwable 类才能 thorw(抛出)或catch(捕获)异常,它是异常处理的基本组成类型。

  Exception 是编码的时候就可以预测到哪些问题,然后捕获处理。且又分为可检测( checked )异常,编译期检查的部分。不可检测( unchecked )异常(也叫运行时异常)。

  Error 是可能导致程序处于非正常、不可恢复的状态。既然是非正常状态,所以不需要捕获;

  典型的 Error 有 NoClassDefFoundError :编译时类可用,在JVM运行时不可用。发生的原因可能是对应的 Class 在 classpath 下不可用、依赖的类库不可用、多个不同的类加载器等等原因。

  典型的 checked 异常:IOException,在编译的时候就可以查看到。

  典型的 unchecked (runtimeExcrption)异常:NullPointException、ClassCastException等。

  捕获异常的原则

    1)、尽量不要捕获 Exception 这样的通用异常,要捕获特定的异常,这样才能直观看到是哪里发生了异常,而不是泛泛的一个 Exception;

    2)、不要生吞异常,直接 catch 后没有下一步动作,要做出处理,例如我们项目现阶段就是在后台用日志插件打印出来。

2、强引用、软引用、弱引用、幻象引

  在Java语言中,除了几种基本数据外,其他的都是指向各个对象的对象引用。

  强引用:我们常在代码写的 Object o = new Object(); 就是一个强引用,JVM就算内存空间不足,抛出错误使JVM异常终止,也不会清空这些内存,只能显示赋值null回收或者超过了引用的作用域;

  软引用:通过SoftReference类实现,比强引用的生命周期短一点。 如果JVM内存满了,就会适当清楚软引用。可以和一个引用队列结合使用,当软引用所引用的对象被垃圾回收器回收,就会加入该引用队列,后续可以使用引用队列的poll()方法检查它关心的对象是否被回收,用于内存敏感的的缓存中;

  弱引用:当JVM的垃圾回收器线程扫描它管理的内存,一旦发现弱引用,就会直接回收该引用,也可以配合引用队列使用,用于内存敏感的的缓存中;

  幻象引用:必须配合引用队列使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。可用来跟踪对象被垃圾回收器回收的活动,当一个虚引用关联的对象被垃圾收集器回收之前会收到一条系统通知。

3、String、StringBuffer、StringBuilder

  String:是典型的不可改变类,用的 final 修饰的。当对某个字符串拼接、裁剪,由于它的不可改变性质,都会产生新的字符串常量,放在常量区中,可以被多个线程拷贝使用。

  StringBuffer 和 StringBuilder 都是为了应对操作 String 时产生更多的对象而提供的类。通过append 和 add 方法,在字符串指定位置或末尾添加字符串。 StringBuffer 和StringBuilder相比是线程安全,因为 StringBuffer 修改数据的各种方法都加了 synchronized 关键字,所以线程安全,但是也增加了额外的性能消耗。

  绝大部分情况都是用的 StringBuilder 来进行字符串的拼接。
  扩展知识点
    StringBuilder初始构建长度为创建的字符串长度 + 16。如果长度在之后超过了该长度,就会重新创建一个数组,把该数组 arraycopy。
    字符串缓存:避免创建重复字符串,降低内存消耗和减少创建对象的开销。方法是 intern() 。
    在Java6中不推荐把字符串缓存,因为会存到一个永久代,因为存的字符串大小有限,并且基本不会除FullGC之外的垃圾器回收到。在后续版本,该缓存放到了堆中,避免永久代占满以及默认缓存的大小也变大了。
    在Java9以后将用 bytes 数组存数据(以前是 char 数组存数据)。紧凑字符带来了占用更小的内存和更快的速度。

4、动态代理

  反射:运行状态时动态获取任意一个类的所有属性和方法,或获取任意一个对象的所有属性和方法。

  动态代理:运行时动态构建代理、动态处理代理方法的机制。例如AOP和RPC调用都是用了该机制。实现的方式有反射、JDK自身提供的动态代理机制。

  扩展知识点

    代理是对调用的目标的一个封装,使得对目标代码的调用不是直接发生的,而是通过代理完成。

5、int 和 Integer的区别

  Integer 是 int 的包装类,有一个 int 类型的字段储存数据,并且提供了基本操作,比如数学运算,int 和字符串之间的转换。并且在Java5以后引入了自动装箱(Integer.valueOf)和自动拆箱(Integer.intVaule)。自动装拆箱都涉及到内存资源的消耗,所以需要避免无意义的装拆箱。Integer 是对象的引用,会创建对象,所以如果创建数量太大的话会消耗很多资源。

该文章只是笔记,记录的是我自己大概的总结。

如果想看完整的知识点,可以去 极客时间app 上找 Java核心技术36讲 --- 杨晓峰 老师的课程。

链接:https://time.geekbang.org/column/82

原文地址:https://www.cnblogs.com/AlmostWasteTime/p/10250691.html