碎片小知识

本文总阅读量
本文最后更新于2 分钟前,文中所描述的信息可能已发生改变。

有关java的一些零散知识点。

java基础

Comparable与Comparator两个接口的区别

Comparable(java.lang)接口:实现此接口只能定义一种排序规则,通过实现接口中的int compareTo(T o)方法来比较,需要待排序类自己实现。

Comparator(java.util)接口:使用此接口待比较对象不需要自己实现,即可以保持待比较类的原样实现比较功能。实现此接口的类即为比较器,可以在此类中的compare方法中定义比较规则,通过多个比较器可以实现按照不同属性进行排序的功能。

equals()与hashCode()

"="比较的为地址,equals()比较两个对象是否等价(值是否相等)。重写了equals()方法一定要重写hashCode()方法,等价的两个对象hashCode一定相等但是hashCode相等的两个对象不一定等价,hashCode的计算具有随机性导致。HashMap(key使用)与HashSet是使用hashCode来计算对象的存储位置,所以当重写了equals而不重写hashCode方法会导致在集合中添加相同的元素。

浅拷贝与深拷贝

浅拷贝:拷贝对象与原始对象的引用(地址)是相同的,拷贝的是引用。 深拷贝:拷贝对象与原始对象的引用不同,拷贝的是值。

Object中的clone()方法为浅拷贝。使用此法需要实现Cloneable接口,既复杂又有风险,还需要进行类型转换不推荐使用此方法进行拷贝。可以使用对象拷贝工厂或拷贝构造函数来进行拷贝一个对象。例如

java
public class A{
    public int age;
    ...
    //拷贝构造函数
    public A(A a){
        this.age = a.age;
        ...
    }
}

接口与抽象类

  • 接口:方法和字段默认都是public(只能为此),且字段默认都是是static final修饰。java8开始接口中的方法可以有默认实现,java9开始方法可以被private修饰(这样就可以定义一些私密的复用代码,即只在本接口中使用的)。
  • 抽象类:访问修饰符没有限制,只能被继承不能实例化。
  • 使用时机:
    • 接口:需要让不相关的类都实现同一个方法、需要使用多重继承。
    • 抽象类:需要让相关的类中共享代码、需要控制方法的访问权限、需要继承非静态字段与非常量字段。

重写与重载

  • 重写:外壳不变,核心改变(返回值类型需为父类方法中的返回值类型或其子类,异常与访问权限也是如此,即只能小不能扩大范围)。
  • 重载:方法名相同,但参数列表要唯一(即参数类型、个数、顺序至少有一个不同)。

泛型

泛型是一种特殊的类型,即在创建对象或调用方法时才会明确其具体的类型。主要使用有泛型类、泛型接口、泛型方法。静态方法访问不到类上的泛型声明,需要自己声明(即定义为一个泛型方法)。

java
/* 泛型类的声明 */
public class Ciallo<T>{
    public static<T> void A(T a){
        //这个类型T的实际类型可以与类上声明的T类型相同也可不同
        System.out.println(a);
    } 
    public void B(T b){
        //这个T类型必须和类上声明的T类型一致
        System.out.println(b);
    }
    //泛型方法的声明
    public <T> void C(T c){
        //这个T是一个新的类型T,即可以与类上的T类型相同也可不同
        System.out.println(c);
    }
}

部分内容参考自

java基础

java容器

分为两大类Collection与Map。

Collection:

  • Set:
    • TreeSet:基于红黑树实现,支持有序性操作。
    • HashSet:基于哈希表实现,支持快速查找,但不支持有序性操作。并且失去元素的插入顺序信息。
    • LinkedHashSet:具有 HashSet 的查找效率,并且内部使用双向链表维护元的插入顺序。
  • List:
    • ArrayList:基于动态数组实现,支持随机访问。
    • Vector:和 ArrayList 类似,但它是线程安全的。
    • LinkedList:基于双向链表实现,只能顺序访问,但是可以快速地在链表中插入和删除元素。不仅如此,LinkedList 还可以用作栈、队列和双向队列。
  • Queue:
    • LinkedList:可以用它来实现双向队列。
    • PriorityQueue:基于堆结构实现,可以用它来实现优先队列。

Map:

  • TreeMap:基于红黑树实现。
  • HashMap:基于哈希表实现。
  • HashTable:和 HashMap 类似,但它是线程安全的,它是遗留类,不应该去使用它,而是使用 ConcurrentHashMap 来支持线程安全。

源码学习

ArrayList的扩容:默认数组大小为10(实际是0,只有添加了第一个元素才会生成一个大小为10的数组),扩容后的大小=老的容量大小+老的容量大小>>1,即扩容后为原来的1.5倍,>>1需要取整(偶数时扩容为1.5倍)。

部分内容参考自

java容器

JVM

JDK与JRE

  • JDK(Java Development Kit) Java 开发工具包,提供了 Java 的开发及运行环境。JDK 是 Java 开发的核心,集成了 JRE 以及一些其它的工具,比如编译 Java 源码的编译器 javac 等(JRE+java开发辅助工具)。
  • JRE(Java Runtime Environment) Java 运行环境的简称,为 Java 的运行提供了所需的环境。它是一个 JVM 程序,主要包括了 JVM 的标准实现和一些 Java 基本类库(JVM+java程序运行时所需要的类库)。

JVM的总体机制

JAVA 源程序编译运行过程:java 源程序->编译->.class字节码文件->类加载到 JVM 上运行。

JVM 的总体运行机制:

  • 使用类加载器加载 .class 字节码文件到 JVM 内存中的方法区。
  • 在 JVM 的内存中存储相关数据(类的信息、静态变量、常量)。
  • 在执行引擎中将 .class 翻译为 CPU 能够执行的指令。
  • 将指令发送给 CPU 执行 JVM运行机制

类加载机制

  • 类加载器子系统负责从文件系统或网络中加载.class字节码文件。
  • CLassLoader 只负责字节码文件的加载,由执行引擎来判断此字节码文件是否可以运行。
  • JVM中有四中类加载器(前三中为JVM自带):启动类加载器Bootstrap(爷爷)、扩展类加载器Extension(爸爸)、应用类加载器AppClassLoader(儿子)、用户自定义加载器(程序员自己开发一个继承 java.lang.ClassLoader 的类来定制类加载方式)。其中启动类加载器由C++编写,不是 ClassLoader 的子类,在 java 中打印时为 null。
  • 父子关系(逻辑上):通过parent属性维护。
  • 加载顺序(双亲委派机制):先获取要加载的类所对应范围的类加载器,此加载器不会立即查找而是会将任务上移交给其上一级加载器,一直到顶级的应用类加载器,然后从应用类加载器开始查找,找到就加载并到此为止,否则抛出 ClassNotFoundException。
  • 双亲委派机制的好处:
    • 防止重复加载类,保证了JVM范围内类的全限定名是类的唯一标识。
    • 安全机制,防止恶意替换JRE定义的核心API(沙箱安全机制)。

JVM内存

线程私有

  • 程序计数器: 记录正在执行的虚拟机字节码指令地址(就是记录指令地址),执行的是本地方法则为NULL。
  • JAVA虚拟机栈: 由一个个栈帧组成,栈帧中存储有 局部变量表、操作数栈、常量池应用等信息。
  • 本地方法栈:

线程共有

参考文献

JVM1.6

待定…

其它

在保证x是2的n次方的时候y%x的结果与y&(x-1)的结果是一样的。

SpringBoot中的注解
SpringBoot中的Interceptor(拦截器)与Filter(过滤器)
Valaxy v0.18.5 驱动 | 主题 - Yun v0.18.5
本站总访问量
本站访客数 人次
本站已运行0 天0 小时0 分0 秒后缀