Bota5ky

Java笔记(一):基础

JDK, JRE, JVM

JDK(Java Development Kit)

  • 开发工具
    • 基本类库
    • javac 编译
    • javap 反编译
    • javadoc
  • 运行环境 JRE(Java Runtime Environment)
    • JVM(Java Virtual Mechinal) 不同操作系统的机器指令是有可能不一样的,所以就导致不同操作系统上的JVM是不一样的。凡是编译后是Java字节码的都可以在JVM上运行,如Apache Groovy,Scala and Kotlin等等。
    • JVM工作所需要的类库

Math.Round()

向右取整

Byte范围

Java 中用补码来表示⼆进制数,补码的最高位是符号位,最高位用0表示正数,最高位1表示负数,正数的补码就是其本身,由于最高位是符号位,所以正数表示的就是0111 1111,也就是127。最⼤负数就是1111 1111,这其中会涉及到两个0,⼀个+0,⼀个-0+0归为正数,也就是0-0归为负数,也就是-128,所以 byte 的范围就是 -128 - 127。

Integer 缓存池

它的默认值⽤于缓存 -128 - 127 之间的数字,如果有 -128 - 127 之间的数字的话,使⽤ new Integer
不⽤创建对象,会直接从缓存池中取,此操作会减少堆中对象的分配,有利于提⾼程序的运⾏效率。

例如创建⼀个 Integer a = 24,其实是调⽤ Integer 的 valueOf

UTF-8 和 Unicode 的关系

由于每个国家都有⾃⼰独有的字符编码,所以Unicode 的发展旨在创建⼀个新的标准,⽤来映射当今使用的大多数语⾔中的字符,这些字符有⼀些不是必要的,但是对于创建⽂本来说却是不可或缺的。
Unicode 统⼀了所有字符的编码,是⼀个 Character Set,也就是字符集,字符集只是给所有的字符⼀个唯⼀编号,但是却没有规定如何存储,不同的字符其存储空间不⼀样,有的需要⼀个字节就能存储,有的则需要2、 3、 4个字节。
UTF-8 只是众多能够对⽂本字符进行解码的⼀种⽅式,它是⼀种变长的方式。 UTF-8 代表 8 位⼀组表示 Unicode 字符的格式,使⽤ 1 - 4 个字节来表示字符。

U+ 0000 ~ U+ 007F: 0XXXXXXX
U+ 0080 ~ U+ 07FF: 110XXXXX 10XXXXXX
U+ 0800 ~ U+ FFFF: 1110XXXX 10XXXXXX 10XXXXXX
U+10000 ~ U+1FFFF: 11110XXX 10XXXXXX 10XXXXXX 10XXXXXX

可以看到, UTF-8 通过开头的标志位位数实现了变⻓。对于单字节字符,只占⽤⼀个字节,实现了向下兼容 ASCII,并且能和 UTF-32 ⼀样,包含 Unicode 中的所有字符,⼜能有效减少存储传输过程中占⽤的空间。

char 在 java 中是2个字节。 java 采用 unicode,2个字节(16位)来表示一个字符。所以 char = '中' 合法。

fail-fast 和 fail-safe

  • fail-fast是 Java 中的⼀种快速失败机制, java.util 包下所有的集合都是快速失败的,快速失败会抛出 ConcurrentModificationException异常, fail-fast 你可以把它理解为⼀种快速检测机制,它只能⽤来检测错误,不会对错误进⾏恢复, fail-fast 不⼀定只在多线程环境下存在, ArrayList 也会抛出这个异常,主要原因是由于 modCount 不等于 expectedModCount。
  • fail-safe是 Java 中的⼀种安全失败机制,它表示的是在遍历时不是直接在原集合上进⾏访问,而是先复制原有集合内容,在拷⻉的集合上进⾏遍历。 由于迭代时是对原集合的拷⻉进⾏遍历,所以在遍历过程中对原集合所作的修改并不能被迭代器检测到,所以不会触发ConcurrentModificationException。java.util.concurrent包下的容器都是安全失败的,可以在多线程条件下使⽤,并发修改。

反射的基本原理,反射创建类实例的三种方式是什么

反射机制就是使 Java 程序在运⾏时具有 自省(introspect) 的能力,通过反射我们可以直接操作类和对象,比如获取某个类的定义,获取类的属性和方法,构造方法等。
创建类实例的三种⽅式是:

  • 对象实例.getClass()
  • 通过 Class.forName() 创建
  • 对象实例.newInstance() ⽅法创建

类加载机制

类的生命周期:(class 文件 -> Java虚拟机内存 -> 卸载)

  • 加载
  • 验证
  • 准备
  • 解析
  • 初始化
  • 使用
  • 卸载

类的加载过程:

  • 加载:查找并加载类的二进制数据(Class文件)
    • 方法区:类的类信息
    • 堆:Class 文件对应的类实例
  • 验证:确保加载的类信息是正确的
  • 准备:为类的静态变量进行初始化,分配空间并赋予初始值
  • 解析:是将符号应用转换为直接引用
  • 初始化:JVM对类进行初始化,对静态变量赋予正确值
    • 静态代码块

类加载器:

  • BootStrapClasserLoader C语言实现,加载 JDK/JRE/lib 下类路径 java.* 开头的类
  • ExtClassLoader 扩展类加载器 加载 JDK/JRE/lib/ext 下类路径 javax.* 开头的类
  • AppClassLoader 加载自己定义的类,类路径下面。用户自定义类加载器 可以用流、文件、数据库、网络形式加载

双亲委派模型

当一个类加载器收到了类加载的请求的时候,他不会直接去加载指定的类,而是把这个请求委托给自己的父加载器去加载。只有父加载器无法加载这个类的时候,才会由当前这个加载器来负责类的加载。(这样就保证了我们不能篡改 java.己有的类)

异常

参考文献:看完这篇 Exception 和 Error ,和面试官扯皮就没问题了

Java中的所有异常都来自顶级父类 Throwable(实现 Serializable 接口)。

Throwable下有两个子类Exception和Error。

  • Eror表示非常严重的措误,比 StakOverFlowError 和 0ut0fMemoryError,通常这些误出现时,仅仅想靠程序自己是解决不了的,可能是虚拟机、磁盘、操作系统层面出现的问题了,所以通常也不建议在代码中去捕获这些Eror,因为捕获的意义不大,因为程序可能已经根本运行不了了。
  • Exception表示异常,表示程序出现 Exception时,是可以靠程序自己来解决的,比 NullPointerException、 IllealAcessException等,我们可以捕获这些异常来做特殊处理。Exception的子类通常又可以分为RuntimeException和非RuntimeException两类。
    • RuntimeException 表示运行期异常(又称 uncheckedException),表示这个异常是在代码运行过程中抛出的,这些异常是非检查异常,程序中可以选泽浦获处理,也可以不处理,这些导一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生,比如 NullPointerException、IndexOutOfBoundsException 等
    • 非RuntimeException表示非运行期异常,也就是我们常说检查异常,是必须进行处的异常,如果不处理,程序就不能检查异常通过,如 IOExeption、SQLException 等以及用户自定义的 Exception 异常
posted @ 2023-03-18 21:23  Bota5ky  阅读(17)  评论(0编辑  收藏  举报