java基础知识点


001

java和C/C++ py js比较像

理论知识基础,操作系统,计算机网络,记组,数据结构与算法(加分项)

jvm 使java程序在不同操作系统上运行,class二进制语言

版本:

javase java核心,标准版java ,基本功

javaee 企业级开发,网站应用javaweb

javase -> javaee 循序渐进

jre java运行环境 jdk java开发者工具 开发要装jdk


002

不用配置环境变量

安装中文插件


003

编译:javac Main.java

运行:java Main

编译型语言:编译后运行

解释型语言:解释器

java两个都是


004

共同开发

构建锤子,打包项目

运行

调试 评估

搜索

设置


005

分号结尾 括号匹配

{} 代码块


006

自动清理内存

区分大小写

见名知意,英语单词


007

二进制 0 1

下划线


008

unicode \u0000~\uffff

字符串不是基本类型

BigInteger


009

小数存有效数字

BigDecimal


010

byte -> short (char) -> int -> long -> float -> double

数据类型自动提升 int double


011

a++

++a

b+++a -> (b++)+a 贪心机制

位运算符 & | ^ ~ 与 或 异或 非

三目 = a ? b : c


012

if else

阿里巴巴开发手册建议:表达异常的分支时,少用 if-else 方式

变量属于代码块{} ,超出代码块不再存在

switch case break default break 二分搜索 只能传值


013

for(初始条件;循环条件;更新)

for(;;)比while(true)效率高

for each 语法糖


014

取整 1/2=0.0

break跳一次

continue跳一次的一个


015

99乘法表


016

水仙花


017

递归青蛙

动态规划 上一次结果给下一次做参考,下一次快速得到结果,类推

static void jump(int n){
    int[] arr = new int[n];
    arr[0] = 1;
    arr[1] = 2;
    arr[2] = 3;
    for (int i = 3; i < n; i++) {
        arr[i] = arr[i-1] + arr[i-2];
        System.out.println("第"+(i+1)+"台阶有"+(arr[i])+"种跳法");
    }
}

018

基本类型不是类,不能创建对象,对应包装类


019

public class

class

局部变量作用域在代码块中

类不能定义变量,得有一个对象,静态除外


020

main方法返回void

[返回值类型] 方法名 (参数){

 // 方法体	
	return 结果; 
    void 可省 return
    return;
}

return 提前结束方法

return > break > continue

方法可以改变新类的变量

方法可以相互调用,自己调用自己(递归)

递归等于玩火,阿里巴巴开发手册不建议用递归


021

自己要会设计类


022

形参和返回值不同


023

构造方法赋初值

this代表该类的xxx

有参构造覆盖无参


024

不同对象操作同一个静态变量,所有对象共同拥有 。。

隐式加载

静态方法在对象创建之前,在构造器之前

静态上下文不用 this


025

代码块优先于构造器

静态代码块优先于代码块


026

字符串是对象

contains toUpperCase equals

字符串是不可变的

字符串拼接生成一个新对象

就有了 StringBuilder (append) 链式拼接

sb
        .append("hello")
        .append(",")
        .append("world");

当然,JVM 会自动优化 String -> StringBuilder


027

包本质是文件夹

默认导入 lang 包

利用包导入方法

静态导入不会类初始化


028

private 内部访问

和文件名相同的类只能 public


029

数组是 C++ 写的

C 可以越界,java 数组越界异常

arr.length 是 final 类型,数组长度不可变

foreach 语法糖,简化下标定义


030

遍历多维数组 - 多次for循环

deepToString 直接遍历

数组应用:可变长度,就是传数组

可变长参数放到最后一位


031

冒泡

static void test(int[] arr){
    for (int j = 0; j < arr.length - 1 ; j++) {
        boolean b = true;
    for (int i = 0; i < arr.length - 1 - j; i++) {
        if (arr[i] > arr[i+1]){
            b = false;
            int temp = arr[i];
            arr[i] = arr[i+1];
            arr[i+1] = temp;
        }
    }
    if (b) break;
    }
    for (int i : arr) {
        System.out.print(i + " ");
    }
}

032

插入

static void test(int[] arr){
    for (int i = 1; i < arr.length; i++) {
        int temp = arr[i];
        int j = i-1;
        while (j >= 0 && arr[j] > temp){
            arr[j+1] = arr[j];
            j--;
        }
        arr[j+1] = temp;
    }
}

033

选择

static void test(int[] arr){
    for (int i = 0; i < arr.length - 1; i++) {
        int min = arr[i], pos = i;
        for (int j = i+1; j < arr.length; j++) {
            if (arr[j] < min){
                min = arr[j];
                pos = j;
            }
        }

        int temp = arr[i];
        arr[i] = min;// arr[i] = arr[pos];
        arr[pos] = temp;
    }
}

034

super 代表父类,super调用必须是第一句话,老子第一,this 代表当前类

单继承

Object 祖宗类

hashCode 是 C++ 写的


035

重写不是重载

静态不能重写

定义变量 : 形参 > 本类 > 父类

父类对象指向子类实例,得到的是子类实现(向上转型)

这个父类对象可以强转为子类对象(向下转型)

instanceof 父类引用不知道子类实现的判断

对象 instanceof 类

036

final 类不能被继承

JVM 会优化 final 关键字,用于值不可变的变量

抽象方法必须由子类实现,除非子类也是抽象类,但这样做没有意义

内部类可以直接定义抽象类的方法


037

接口 default 默认实现

属性默认 public static final

接口是多继承的代替方案,java 是多继承


038

怪异的内部类:

成员 静态 局部

匿名 ->


039

-> lambda

仅支持单方法接口


040

枚举 public static final

静态代码块初始化

Status.values();
Status.valueOf();

041

自动装 拆箱

两个包装类生成两个对象(-128~127)

包装类有工具类


042

自己设计类

接口,抽象类

instanceof


043

二分查找

private static int test(int target,int[] arr){
    int start = 0; int end = arr.length - 1;
    while (start <= end){
        int mid = (start + end + 1)/2;
        if (arr[mid] == target) return mid;
        if (arr[mid] < target) start = mid + 1;
        if (arr[mid] > target) end = mid - 1;
    }
    return -1;
}

044

快速排序

static void quickSort(int[] arr,int start,int end){
    if (start >= end)return;
    int k = arr[start],low = start,high = end;
    while (low < high){
        while (low < high && k <= arr[high])high--;
        arr[low] = arr[high];
        while (low < high && k >= arr[low]) low++;
        arr[high] = arr[low];
    }
    arr[high] = k; // arr[low] = k;
    quickSort(arr,start,high-1);
    quickSort(arr,high+1,end);
}

045

0 1 背包

填表


046

指针下标越界异常,空指针异常,算术异常,引起程序问题被抛出

红色报错

编译时异常,运行时异常

错误处理不了,异常可以

47

栈追踪信息

追踪异常位置

e.printStackTrace();
catch(Throwable e) // 自动匹配,捕获异常
    // 可以捕获错误,但没必要
    

48

抛出是交给上一级处理,不用自己捕获处理

丢给虚拟机

假使捕获多次,异常只会最内层捕获

49

自定义 MyException 异常继承 Exception ,捕获异常自动捕获子类异常

finally 一定执行,可以用来关流

先执行 return ,再执行 finally

50

泛型

编译阶段判断数据类型,类型不符合不通过编译

JVM 不支持泛型,编译器自动推断类型

51

泛型参数是对象,不能加 static,本质是 Object 类的对象,不能表示基本类型

泛型方法可以加 static

52

通配符

用的很少,框架和反射中会用

前面 <?> 后面 < String >

前面 < String > 后面 <> -> 钻石运算符

// 		前				后
<? extends Number>   
    // 泛型上界 Number
<? super Integer>   
    // 泛型下界 Integer

规定上界后泛型类要在上界之下

下界同理

指定了上限后,没有泛型 Object 的说法了

53

泛型定义在接口,接口中的< T >被 替换 / 擦除

泛型接口反编译会发现两个 桥接方法

@Override
public Object get(){
    return this.get();
}
------------------------
@Override
public void set(Object t){
    this.set((Number)t);
}

054

顺序表

数组定长度是一大痛点,有数据结构(存储数据的一些结构)

线性表是一种数据结构,顺序表是线性表的实现

查询效率高

055

链表

链表注意指针(引用)的指向改变

增删效率高

56

只能在一端 入栈 出栈

基于顺序表和链表实现

size 是栈顶指针

JVM 处理方法嵌套调用就是利用栈调用

57

队列

队尾入队,队头出队

58

二叉树

最多两个子节点

前序 中序 后序遍历

指的是打印当前节点的位置 前中后

59

哈希表

提高查询效率

顺序表虽然查询效率高,但是增删效率低

链表则相反

哈希表折中,是存放链表数组

查找 hashcode 值是数组,增删是链表

60

二叉排序树

每个节点左子树小于当前,右子树大于当前

平衡二叉树

失衡情况,对应处理

左左失衡

右旋

右右失衡

左旋

左右失衡

先左旋再右旋

右左失衡

先右旋再左旋

61

红黑树

失衡严重的情况

image-20220614202942388

出现大量的旋转,但旋转次数不会超过3次

HashMap 中使用 红黑树

节点红色,子节点必黑色,不能相同,颜色交错

62

集合类

是 Java 内置的数据结构

数组和集合都是存储数据的 容器

Set 不能随机访问,不是有序的

List 支持了 Collection 中没有的 get

queue 有两个增删查,一个抛异常的

63

ArrayList

add

remove

contains

直接打印 .sout

64

LinkedList

sort 定义比较器 Comparator

可以简化成 lambda 表达式

65

迭代器

ArrayList 适合随机访问 , LinkedList 适合顺序访问

迭代器解决了这种差异,foreach 的本质就是迭代器

66

Set 集合

不能出现重复元素,不通过下标访问

核心是hash表

HashSet 无序(常用的 Set),LinkedHashSet 有序

TreeSet 自动排序,底层是红黑树

67

key - value

68

HashMap

存放后续节点的头节点的数组

数据变多

负载因子扩容机制

红黑树

HashMap 无序,LinkedHashMap 有序

TreeSet 继承 LinkedHashMap

69

TreeMap

内含比较器:可自定义排序规则

70

Set 就是用 Map 的 key,就是 Map 的代理

Map 是 Set 的师傅

compute merge 计算

71

集合的嵌套,就是套娃

Stream

用声明的方式处理数据,工厂流水线的感觉

list = list
        .stream() // 获取流
        .filter(e -> !e.equals("B"))
        .collect(Collectors.toList());

72

Optional 自动判空,不执行 null

原理是 Kotlin

73

Arrays

二分搜索前提是有序

二维数组遍历 deepToString() 方法 比较 deepEquals() 方法

74

链表反转,递归思想

75

二叉树重建 关键:中序

76

栈实现计算器

77

字符串匹配 - KMP 算法

转化为字符数组

78

I/O 设备

操作系统是管理硬件和软件的软件

79

// 路径分割符
D:/
D:\\ 转义

及时关流,浪费资源

字节流读字节

80

字符流读字符

不适合二进制文件

81

File 类

对文件 / 文件夹操作

82

缓冲流

文件流速度达不到内存读取速度,缓冲流有缓冲区

装饰者模式

BufferedReader 里的 lines 支持链式结构(stream)

缓冲流好处多多,比文件流好多了,尽量用缓冲流

83

转换流

字节转字符 ->

OutputStreamWriter

InputStreamReader

可以再套一层 Buffer 缓冲流

就是套娃

打印流

PrintStream 就是 System.out

自动刷新

不会抛出异常

格式化任意类型

这个流中有多次套娃

84

数据流

可以直接读取基本数据类型

DataOutputStream DataInputStream

对象流

ObjectInputStream ObjectOutputStream

对象实现接口 Serializable

对象有自己的版本序列号 serialVersionUID 用于版本匹配

transient 关键字 ,不参与序列化

源码会使用很多这个关键字

85

线程中有进程

线程是程序运行最小单位

上下文切换速度快于进程

86

创建和启动

休眠方法:Thread.sleep();

强行终止:thread.stop(); 不推荐用

87

休眠和中断

代替stop : 用interrupt();

currentThread() 获得当前线程

suppend 暂停 resume 恢复(过时)

88

优先级

MI N_PRIORITY

MAX_PRIORITY

NORM_PRIORITY

只是执行概率高了,不是必须的

礼让和加入

礼让:yield()

加入:join()

89

线程同步

90

synchronized(Main.class){} 同步代码块

1 + 1 = 2

是一种悲观锁

synchronized(s1){}
synchronized(s2){}
// 拿到锁不一样,结果改变

方法前也可以加锁

死锁

两个线程拿到对方的锁

91

wait 释放锁 进入等待

notify 唤醒等待

92

ThreadLocal

线程的集合类

各自进行各自的,互不干扰

93

守护

setDaemon(true);

并行流

多线程执行方法

parallelStream();

多线程会产生异步问题

94

生产者消费者模式

95

加载 class 文件

96

获得 class 对象

97

Class c1 = String.class;

Class<?> c2 = Class.forName("java.lang.String");
Class<? extends String> c3 = new String("3").getClass();

基本数据类型也有class,自动装箱

98

instanceof 类型比较

getSuperclass();

99

创建类对象

Class c = Student.class;
Student student = c.newInstance(); // 默认调无参构造
student.hello();

c.setAccessible(true); // 强行访问权限

100

方法

Class c = Student.class;
Student student = c.newInstance();
Method hello = c.getMethod("hello");
hello.setAccessible(true);
hello.invoke(student);

101

修改类属性

Class c = Student.class;
Student student = c.newInstance();
Field name = c.getDeclaredField("name");
name.setAccessible(true);
name.set(student,"h");
Method method = c.getDeclaredMethod("getName");
method.setAccessible(true);
Object invoke = method.invoke(student);
System.out.println(invoke);

反射可以刨祖坟了,除非 final (这个改不了)

反射一般不会用,除非迫不得已,不能滥用。。。。。。

技术不是就要用牛逼的,要分场合解决问题

102

ClassLoader

103

注解

编译完就没了

@Override
@Deprecated // 弃用
@SuppressWarnings
@Functionalinterface
@SafeVarrags
@Test // 单元测试

元注解

是编写注解里的注解

@Target
@Inherited

104

注解使用

注解传参

反射获取注解

clazz.getAnnotations();