三个月呕心巨制!Java必备知识点

2023-12-29 22:40

本文主要是介绍三个月呕心巨制!Java必备知识点,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • Java基础
    • 数组常见异常
      • 第一种:
      • 第二种:
      • 第三种:
    • array复制
    • array元素反转
    • 数组排序
  • 面向对象
    • 总结
    • overload重载
    • 匿名类对象
    • 可变个数的形参的方法(数据类型要一样)
    • *方法参数传递*
    • 面向对象特征之一: 封装(Encapsulation)
    • 类的成员之三: 构造器(constructor)
    • this
    • package
    • import
    • 面向对象特征之二:继承(inheritance)
      • override重写
      • super
    • 面向对象特征之三: 多态性
      • object类
      • toString方法
      • Wrapper包装类
    • static
    • 类的成员之四: 代码块
    • final
    • Abstract
    • interface 接口
    • 类的成员之五: 内部类
  • 异常处理(Exception&Error)
    • common *RuntimeException*:
    • 如何处理异常
  • 集合
    • Collection接口
    • Map接口
    • Collections工具类
  • 泛型 generics
    • 集合中的泛型
    • 自定义泛型类
    • 泛型和继承
    • 通配符
  • 枚举 Enum type
  • 注解 Annotation
  • IO
    • File类
      • 节点流
      • 缓冲流
      • 转换流
      • 标准输入输出流
      • 打印流
      • 数据流
      • 对象流
      • RandomAccessFile
  • 多线程
    • java.lang.Thread类
      • Thread 常用方法
    • java.lang.Runnable接口
    • 线程的生命周期
    • 线程的同步
    • 线程通信
  • 常用类
    • String类
    • StringBuffer
    • StringBuilder
    • 日期类
    • Math类
    • BigInteger/BigDecimal
  • 反射
    • Class类
    • 获取Class类的对象
    • 创建类对象并获取其完整结构
    • 调用指定属性, 方法, 构造器
    • 动态代理
  • 网络编程
    • 网络基础

Java基础

数组常见异常

  • ArrayIndexOutofBoundsException
public static void main(String[] args) {int[] i = new int[10];i[10]= 99;
  • NullPointerException

第一种:

boolean[] b = new boolean[3];
b = null;
System.out.println(b[0]);

第二种:

String[] str = new String[4];
System.out.println(str[3].toString());

第三种:

int[][]j = new int[3][];
j[2][0] = 33;

array复制

int[] array1, array2;
array1 = new int[] { 2, 3, 8};
/* 
array2 = array1
error:如果修改array2会同时修改1,因为这样只是传递了地址给2
*/
array2 = new int[array1.length];
for (int i = 0; i < array1.length; i++){array2[i] = array1[i];
}

array元素反转

int[] arr = new int[]{ 9, 88, 5};
for(int i = 0;i < arr.length/2;i++){int temp = arr[i];arr[i] = arr[arr.length - 1 - i];arr[arr.length - 1 - i] = temp;
}//第一种
/*第二种
for(int x = 0,y = arr.length - 1;x < y;x++,y--){int temp = arr[x];arr[x] = arr[y];arr[y] = temp;
}
*/

数组排序

  • 冒泡

    public static void main(String[] args) {int[]arr = new int[]{49,343,45,87,3,13,67};for(int i = 0; i < arr.length -1; i++){for(int j = 0; j < arr.length -1 - i; j++){if (arr[j] > arr[j+1]) {int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}System.out.println("从小到大排序以后:");for(int i = 0; i < arr.length; i++){System.out.println(arr[i] + "\t");}}
    
  • 直接选择顺序

    public static void main(String[] args) {int[]arr = new int[]{49,343,45,87,3,13,67};for(int i = 0; i < arr.length - 1; i++) {int t = i;//默认i是最小for(int j = i; j < arr.length; j++) {//一旦在i后发现存在比i小的元素,记录那个下角标if(arr[t] > arr[j]) {t = j;}}if(t != i) {int temp = arr[t];arr[t] = arr[i];arr[i] = temp;}}System.out.println("从小到大排序以后:");for(int i = 0; i < arr.length; i++){System.out.println(arr[i] + "\t");}// TODO Auto-generated method stub}
    

面向对象

总结

overload重载

同一个类中,方法名相同,而参数列表不同(类型/个数),与返回类型无关

class Overload{public int getSum(int i,int j){return i + j;}public int getSum(int i, int j, int k){return i + j + k;}public int getSum(double a, double b){return a * b;}public void getSum(double a, double b, double c){System.out.println(a + b + c);}
}
class Overload{public void method(int i, String j){}public void method(String j, int i){}
}

匿名类对象

创建的类的对象是匿名的

  • 只需要一次调用类的对象
p.printAreas(new Circle(), 6);
//System.out.println(c.getRadius);

可变个数的形参的方法(数据类型要一样)

  • 调用时, 个数从0开始
// 以下三个sayHello()仍为overload
public void sayHello(String str1){System.out.println("hello" + str1);
}
public void sayHello(){for(int i = 0; i < args.length; i++){System.out.println(args[i]);}
}
// 可变个数形参
public void sayHello(String... args){for(int i = 0; i < args.length; i++){System.out.println(args[i]);} 
}
  • 若方法中存在可变个数的形参,一定要声明在最后
public void sayHello(int i, String... args){for(int i = 0; i < args.length; i++){System.out.println(args[i]);} 
}
  • 一个方法只能有一个可变个数的形参

方法参数传递

pass by value 值传递:

  • argument是primitive: 将parameter的值传递给argument的基本数据类型变量
  • argument是reference: 将reference的值(对应堆空间的对象实体的首地址值) 传递给argument的引用数据类型变量

面向对象特征之一: 封装(Encapsulation)

问题: 不让对象直接作用属性,而是通过“方法.属性”来控制对象对属性的访问

  • 封装:
    1. 将类的属性私有化
    2. 提供公共方法来实现调用
public class TestAnimal {public static void main(String[] args){Animal a1 = new Animal();a1.setLegs(4);a1.setname("花花");a1.getLegs();a1.getName;}
}class Animal{private String name;private int legs;//private 修饰的属性只能在本类中来调用,出了本类,只能用公共方法来调用public void setLegs(int l){if(l > 0 && l % 2 ==0){legs = l;}else{System.out.println("您输入的数据有误");}}public void setName(String n){//...name = n;}//设置类的属性public int getLegs(){return legs;}    public String getName(){return name;}//获取类的属性
}
  • class/ method 权限修饰符: public protected default private
修饰符类内部同一个包子类任何地方
privateyes
(default)yesyes
protectedyesyesyes
publicyesyesyesyes

class 只能用(default)和 public

类的成员之三: 构造器(constructor)

前两个是属性(field),方法(method)

作用:

1. 创建对象
2. 给创建的对象的属性赋值
  • 如何声明: 权限修饰符 类名 (形参) { }
  • 设计类时, 若不显式声明类的构造器, 程序会默认提供一个空参的构造器
  • 有显式的定义类的构造器, 不在提供默认的构造器
  • 类的多个构造器之间构成重载
public class TestPerson{public static void main(String[] args){//Person p1 = new Person(); 默认的空参Person p2 = new Person("Jack", 23);System.out.println(p2.getName);System.out.println(p2.getAge);// Jack  0Person p3 = new Person("Rose", 22);System.out.println(p3.getName + "\t" + p3.getAge); //Rose	22 }
}class Person{// 属性private String name;private int age;// 构造器 public Person(String n){name = n;}public Person(int m){age = m;}public Person(String n, int m){name = n;age = m;}// 方法public void setName(String n){name = n;}public void setAge(int m){age = m;}public getName(){return name;}public getAge(){return age;}}

类对象的属性赋值先后: 1. 默认初始化 2. 显式 3. 构造器 4. “对象.方法()”

this

  • this.当前对象或当前正在创建的对象

  • 可修饰 属性, 方法, 构造器

  • 在构造器中, “this(argument)”: 调用当前类重载的指定构造器

    • 在构造器内部必须是首行!
    • 若一个类中有n个构造器, 那么最多有 n - 1 个构造器中使用this(argument), 否则会出现环路
class Person{private int age;private String name;public Person(String name){this.name = name;}public Person(int age){this.age = age;}// this.age: 当前正在创建的对象public Person(int age, String name){this(age);// 显式的调用当前类的重载的指定构造器this.name = name;// this(name);}public void setAge(int age){this.age = age;}//this.age: 当前对象public void info(){System.out.println("age:" + this.age);this.show();// this.show(): 当前方法}public void show(){System.out.println("我是一个人,我的年龄是:" + this.age);}
}

package

  • 声明源文件所在的包, 写在程序的第一行

  • 每**"."**一次, 表示一层文件目录

    package study.qinghu.java
    
  • 小写

import

  • 显式导入指定包下的类或接口

  • 若导入java.lang包下的,如: System, String, Math, etc, 不用显示声明

  • “.*”

    import java.util.*
    
  • 同名类的导入, 如: 在util包和sql包下同时存在Date类

    import java.util.*...Date d = new Date();java.sql.Date d1 = new java.sql.Date(23423428L);
    
  • import static 表示导入指定类的static的属性/方法

  • 只能导入包下的所有类/接口, 不能导入子包下的类或接口

面向对象特征之二:继承(inheritance)

public class Person{public void eat{System.out.println("吃饭");}
}
public class Worker extends Person{public static void main(String[] args) {Student s = new Student();s.eat();}
}
  • 当父类中有private class或method,子类获取的到,但由于封装性,使得子类不能直接调用
  • 单继承: 子类只能extends一个父类, 一个父类可以有多个子类

override重写

对父类重名的类进行重写. 修饰符 返回值类型 方法名 (参数列表) { }

public class Worker extends Person{public void eat() {System.out.println("工人吃饭");}
}
  • 原因: 子类继承父类后, 若父类的方法对子类不适用, 那么子类可以对父类的方法覆盖

  • 规则:

    1. 子类方法的" 返回值类型 方法名 (参数列表) { }" 与父类方法一样
    2. 子类方法的修饰符 >= 父类方法
    3. 子类方法抛的异常 <= 父类
    4. 子父类的方法必须同为static或同为非static

super

  • 父类 属性, 方法, 构造器
  1. 当子类与父类有同名的属性时, 可以通过"super.属性" 显式的调用父类中同名的属性; "this.属性"调用子类中同名的属性

  2. 当子类重写父类的方法后, "super.方法"在子类中显式调用父类中被重写的方法

  3. 在子类中使用"super(形参列表)"来显式的调用父类中指定的构造器

    • 在构造器中, "super(形参列表)"必须声明在首行. 所以super和this只能出现其中一个
    • 在构造器中, 不显式调用"this(argument)"或"super(argument)"任何一个, 默认调用的是父类空参的构造器
  4. 建议: 设计一个类时, 尽量要提供一个空参的构造器

面向对象特征之三: 多态性

  1. 多态性

    1. 方法的重载和重写

    2. 子类对象的多态性

  2. 子类对象的多态性使用前提:

    1. 要有类的继承
    2. 子类对父类方法的重写
  3. 编译和运行
    编译时, “看左边”, 将此引用变量理解为父类的类型
    运行时, “看右边”, 关注真正的对象的实体: 子类的对象. 执行的方法就是子类重写的.

  4. 向下转型:

    1. 强转符: Man m1 = (Man) p1;

    2. 保证不报错ClassCastException, 最好向下转型前, 进行判断: if (p1 instanceof Woman){ }

  5. 子类对象的多态性, 并不适用于属性. 即"看左边"

public class JavaPolymorphism {public static void main(String[] args) {...//子类对象的多态性,父类的引用指向子类对象Person p1 = new Man();//向上转型//虚拟方法调用: 通过父类的引用指向子类的对象实体, 实际执行的是子类重写父类的方法p1.eat();p1.walk();//p1.shaving(); 编译不通过, 因为Person类里没有Man类的方法Man m1 = (Man)p1;//向下转型, 使用强转符m1.shaving();
//      Women w = (Woman)p1; 
//      w1.shopping;编译通过, 运行报错//instanceof:返回值booleanif (p1 instanceof Woman) {Woman w1 = (Woman)p1;w1.shopping();}if (p1 instanceof man) {man m1 = (man)p1;m1.shaving();}}
}

object类

  • java.lang.Object 类, 是所有类的根父类
  • 仅有一个空参构造器: public Object() {}
  • method:
    • equals()

      1. 只能比较引用类型变量
      2. 比较两个变量的地址值是否相等
Person p1 = new Person();
Person p2 = new Person();
System.out.println(p1.equals(p2));//false
System.out.println(p1 == p2);//false

​ 3. String,Package类 ,File类 , Data类 重写Object类的equals()方法, 比较两个对象的"内容"是否完全相同

String str1 = new String("AA");
String str2 = new String("AA");
String str3 = "AA";
String str4 = "AA";
System.out.println(str1 == str2);//false
System.out.println(str1.equals(str2));//true
System.out.println(str3 == str4);// true "AA"在常量池
System.out.println(str1.equals(str3));// true
 		4. 自定义一个类, 希望比较两个对象的属性值都相同的情况下返回true, 就需要重写equals(Object obj)方法
//自定义
public boolean equals(Object obj){if (this == obj){return true;}if (obj instanceof Person){Person p = (Person)obj;return this.equals(p.name) == p.name && this.age == p.age;} else {return false;}
}

== :

  • primitive: 比较值
  • reference: 比较地址值

toString方法

  • java.lang.Object.toString:

    public String toString() {return getClass().getName() + "@" + Interger.toHexString(hashCode());
    }
    
    • 当打印一个对象的引用时, 默认调用的是这个对象的toString()方法

    • 当打印的对象所在类没有重写Object中toString()时, 那么调用的是Object定义的返回对象所在的类及对应的堆空间对象的首地址值

    • 常常如下重写了toString(), 将对象的属性信息返回

      public String toString() {return "Person: name = " + name + " age= " + age;
      }//手动//自动
      
    • String, Wrapper, File, Data, 已经实现了Object中toString() override

Wrapper包装类

PrimitiveWrapper
booleanBoolean
byteByte
shortShort
intInteger
longLong
charCharacter
floatFloat
doubleDouble
  • Wrapper 默认null
  • autoboxing/ unboxing
  • Wrapper与Primitive, String相互转化

    @Test
    public void test2() {//Primitive, Wrapper ---> String: int i1 = 10;String str1 = i1 + "";//"10" 方法1Integer i2 = i1;String str2 = String.valueOf(i2);//方法2: 调用String override的valueOf(Xxx x)方法String str3 = String.valueOf(true);//String--->Primitive, Wrapper:int i3 = Integer.parseInt(str2);//方法1:  调用Wrapper的静态的parseXxx(String)方法boolean b1 = Boolean.parseBoolean(str3);}@Test//Primitive <---> Wrapper
    public void test1(){int i = 0;System.out.println(i);boolean a = false;Integer i1 = new Integer(i);System.out.println(i1.toString());Float f = new Float(22.5F);//Float f = new Float("22.5F");System.out.println(f);//java.lang.NumberFormatException//i1 = new Integer("12abc");//System.out.println(i1);Boolean b = new Boolean("false");System.out.println(b);//"false"//Boolean: 当形参是"true" 返回true, 除此之外返回falseBoolean b1 = new Boolean("trueabc");System.out.println(b1);// "false"Order o = new Order();System.out.println(o.c);//null//Wrapper ---> Primitive: 调用包装类Xxx的XxxValue()方法int i2 = i1.intValue();System.out.println(i2);//JDK 5.O后, autoboxing,unboxingInteger i3 = 30;//autoboxingBoolean jj = false;int i4 = i3;//unboxing
    }class Order{Boolean c;
    }
    

static

static修饰属性, 方法, *代码块, *内部类

  • static修饰属性(类变量)

    • 由类创建的所有的对象, 都共用这一个属性, 存在静态域中. 对此属性进行修改, 会导致其他对象对此属性的调用.

      实例变量(非static修饰的变量,各个对象各自拥有一套副本)

    • 类变量随着类的加载而加载,早于对象, 且只一份

      实例变量(随着对象的创建而被加载)

    • 静态的变量可以直接通过"类.类变量"来调用, 也可以通过"对象.类变量"来调用, 但是"类.实例变量"不行.

  • static修饰方法(类方法)

    • 只能调用静态的属性和静态的方法, 非静态的方法能调用静态的属性和方法
    • static修饰的方法里不能有this|super
  • constructor 看作和方法一样

静态的结构(static的field method 代码块 内部类)生命周期比非静态结构长: 加载早于非静态, 被回收晚于非静态

static变量的内存结构图

应用:

利用静态的变量达到累加的效果, 因为静态的内容独一份,被多个对象所共用, 比如记录创建对象的次数/ 每个对象某个属性有关联

public class TestAccount {psvm{Account a1 = new Account("abc", 1000);Account a2 = new Account("CDF", 2000);sout(a1);sout(a2);}
}
class Account{private int id;//账号private String password;private double balance;private static double minbalance = 1;private static double rate = 0.05;//利率private static int init = 1000;//初始金额public Account(String password, double balance) {this.id = init++;this.password = password;this.balance = balance;}...
}

类的成员之四: 代码块

  • 代码块只能有static修饰

  • 非静态代码块:

    • 对类的属性(静态||非静态)进行初始化
    • 可以有输出语句
    • 一个类中可以有多个代码块,多个代码块之间按照顺序结构执行
    • 每创建一个类的对象, 非静态代码块就加载一次
    • 非静态代码块的执行早于构造器

属性赋值的操作:

①默认的初始化

②显式的初始化||初始化块(此两结构按照顺序执行)

③构造器

——— 以上是对象的属性初始化的过程———

④通过方法对对象的相应的属性进行修改

  • 静态代码块
    • 可以有输出语句
    • 随着类的加载而加载, 而且只被加载一次
    • 多个静态代码块按照顺序执行, 均早于非静态
    • 静态代码块中只能执行静态的结构(类属性,类方法)
public class TestOrder {psvm {Order o1 = new Order();sout(o1);Order o2 = new Order();sout(o2);}
}
class Order{private int orderId = 1001;private String orderName;//静态代码块{orderId = 1002;orderName = "AA";sout("我是非静态代码块1")}//我是非静态代码块1//Order[orderId = 1002, orderId = AA]static{sout("静态代码块3")}//静态代码块3//我是非静态代码块1//Order[orderId = 1002, orderId = AA]...
}

final

  • 修饰类, 属性, 方法

    • final class: 不能被继承, eg. String, StringBuffer, System

    • final method: 不能被重写, eg. Object.getClass()

    • final field: 此属性是常量. 用大写字符, eg. final int L

      在哪赋值: ①不能默认赋值②可以显式赋值: 代码块, 构造器

    • 全局常量: 被static, final修饰, eg. Math.PI

      public static final double PI

diff: finally, finalize()

Abstract

  • 可以修饰类, 方法

  • 不能被实例化, 但可以定义构造器

    所有类都有构造器

  • 有抽象方法的一定是抽象类, 抽象类不一定有抽象方法

  • 若子类继承抽象类, 并重写了所有 的抽象方法, 则此类是"实体类", 即可以实例化;

    若子类继承抽象类, 并未重写了所有 的抽象方法, 则此类仍为抽象类.

public class TestAbstract {psvm {//Person p1 = new Person();//p1.eat;Student s1 = new Student();s1.eat;}
abstract class Person {String name;public Person() {}public Person(String name) {this.name = name;}//abstract methodpublic abstract void eat();public abstract void walk();
}class Student extends Person {public void eat() {sout("student eat");}public void walk() {sout("student walk");}     
}
}

总结: 抽象类作为多个子类的通用模版, 子类在抽象类的基础上拓展.

解决的问题:

  1. 当功能内部一部分实现是确定的, 一部分实现是不确定的. 把不确定的部分放在抽象类, 让子类重写
  2. 编写一个抽象父类, 父类提供子类的通用方法, 并把>= 一个方法留给子类实现.

interface 接口

  • interface是与class并行的
  • 接口看作特殊的抽象类, 包含常量, 抽象方法, 不能包含变量, 一般的方法.
  • 没有构造器, 所以不能创建对象
  • 定义的是一种功能, 可以被类实现(implements)
  • 实现接口的类, 必须重写其中所有 的抽象方法, 才能实例化, 否则仍为一个抽象类
  • 类能实现多个接口(Java中是单继承)
  • 接口与接口之间是继承
  • 只能被public, (default)修饰
public class TestInterface {}interface AA {//常量int I = 12//public static final int I = 12;所有常量都有这些修饰符,所以省略//int i;不能有变量//抽象方法void method1();//public abstract void method1);所有方法都有这些修饰符,所以省略
}abstract class BB implements AA {}
class DD {}
interface MM {void method2();
}//接口被类实现, 类能实现多个接口
class CC extends DD implements AA, MM {public void method1() {} public void method2() {}
}//接口继承接口
interface JJ extends AA, MM {void method1();void method2();
}

类的成员之五: 内部类

  1. 在类的内部再定义类, 外面的类:外部类. 里面的类: 内部类

  2. 分类:

    • 成员内部类: 声明在类的方法外
    • 局部内部类: 声明在类的方法里
  3. 成员内部类:

    • 外部类的成员:
      • 4个修饰符
      • static final
      • 可调用外部类的属性, 方法
    • 类的特点:
      • abstract
      • 还能在内部定义属性, 方法, 构造器
  4. 局部内部类:

掌握:

  • 如何创建成员内部类的对象
  • 如何区分调用外部类, 内部类的变量(尤其是变量重名时)
  • 局部内部类的使用

异常处理(Exception&Error)

common RuntimeException:

  • 空指针 NullPointerException

    @Test
    public void test1() {Person p = new Person();p = null;sout(p.toString());
    }
    
  • 数组下标越界 ArrayIndexOutOfBoundsException

    @Test
    public void test2() {int[] i = new int[10];sout(i[10]);
    }
    
  • 算术异常 ArithmeticException

    @Test
    public void test3() {int i = 10;sout(i / 0);
    }
    
  • 类型转换 ClassCastException

    @Test
    public void test4() {Object obj = new Date();Date向上转型为ObjectString str = (String)obj;将Object向下转型String, 但Date不支持//String str = (String)new Date();编译异常
    }
    

一旦出现异常, 下面的代码就不执行了

如何处理异常

  • 抓抛模型

    1. “抓”: 抓住上一步抛出来的异常类的对象.
    • try-catch-(finally)
    try {//可能出现异常的代码} catch (Exception e1) {//处理的方式1} catch (Exception e2) {//处理的方式2}
    finally {//一定要执行的代码
    }
    
    1. try内声明的变量,类似于局部变量, 出了try{}, 就不能被调用
      finally{ }可省略

    2. catch() 对异常对象的处理:

      • getMessage();
      • printStackTrace();
      1. 可以有多个catch(), try{} 中抛出的异常类从上往下匹配catch()中异常类的类型, 满足一个并执行完处理方式后就跳出其后多条catch(). 异常处理之后的代码可以执行

      2. catch()中多个异常类型是子父类, 子类必须放上面, 否则编译不通过

      3. finally{ }中的代码一定被执行, 不管try{}, catch() {}中是否有仍未处理的异常/ 是否有return

      4. try-catch可以嵌套

    • throws

      在方法声明处, 显式抛出该异常对象的类型.

   public staic void method() throws Exception{...}

​ 2. “抛”: 当我们执行代码时,一旦出现异常,会在异常代码处生成一个对应的异常类型的对象,并将此对象抛出,且程序终止.(自动抛/手动抛)

此异常类的对象抛给方法的调用者

  • 手动抛throw+ 异常类的对象

    throw new RuntimeException("wrong");
    
    • 自定义异常类

      仿造RuntimeException

  • 子类重写父类方法, 抛出的异常类型 <= 被重写的方法抛的异常

集合

image-20200517221016723

Collection接口继承树

Collection接口

  • 方法
public class TestCollection {@Testpublic void testCollection1() {Collection coll = new Arraylist();//1. size();返回集合中元素个数sout(coll.size());//2. add(Object obj);添加一个元素,*默认是object*coll.add(123);coll.add("aa");coll.add(new Date());//3. addAll(Collection coll):Collection coll1 = Arrays.asList(1,2,3);coll.addAll(coll1);sout(coll.size());//6//查看集合元素sout(coll);//Arraylist重写了toString()//4. isEmpty(); return boolean//5. clear(); }@Testpublic void testCollection2() {Collection coll = new Arraylist();coll.add(123);coll.add("aa");coll.add(new Date());coll.add("bb");//6. contains(Object obj)//判断依据: 根据元素所在类的equals()进行判断, //如果存入集合中的元素是自定义类的对象.要求:自定义类要重写euqals()!boolean b1 = coll.comtains(123)//7. containsAll(Collection coll)Collection coll1 = new Arraylist();coll1.add(123);coll1.add("AA");boolean b3 = coll.containsAll(coll1);sout("#" + b3);}
}
  • Iterator接口
public class TestIterator {@Testpublic void testIterator() {Collection coll = new Arraylist();coll.add(123);coll.add("aa");coll.add(new Date());// 迭代器遍历集合Iterator i = coll.iterator();while(i.hasNext()) {sout(i.next());}// foreach遍历for(Object o: coll) {sout(o);}}
}
  • List接口(有序, 可重复)

    • List 方法

      image-20200517230137354

    • ArrayList(List的主要实现类)

      • 本质是对象引用的一个可变数组
      • 线程不安全(vector线程安全, 但效率低, 不使用)
    • LinkedList

      • 链表实现
      • 频繁插入/删除时使用
  • Set接口(无序, 不重复)

    • 无序!=随机

      元素的位置根据hash值存储

    • hashcode(), equals(), compareTo()要重写, 保证得到一致的结果

    • HashSet(主要 实现类)

    • LinkedHashSet

      • 使用链表维护添加 的顺序, 但存储是无序
      • 效率: 遍历>HashSet, 插入删除<HashSet
    • TreeSet

      • 元素是同一类
      • 排序
        • 自然
        • 实现Comparable接口的compareTo()
          • String, 包装类已重写. 升序(小 -> 大, a -> z)
        • 定制
          • 实现Comparator接口的compare()

Map接口

Map接口继承树

HashSet是HashMap的一种特殊情况, 底层实现有关联

  • 保存具有单向一对一的数据

    key, value可以是任何引用类型数据

    key常用Set存, 所以不允许重复, 需重写hashCode(), equals()

    value常用String存

  • 方法

  • HashMap(主要 )

    • 子类: LinkedHashMap 迭代顺序与插入顺序一致
  • TreeMap

    类似TreeSet

  • Hashtable

    • 过时, 线程安全. 不允许null作为key, value

    • 子类: Properties

      key, value都为String. 常用于处理属性文件

      Properties pros = new Properties();
      pros.load(new FileInputStream("jdbc.properties"));
      String user = pros.getProperty("user");
      Sout(user);
      

Collections工具类

  • 提供静态方法操作Collection, Map的元素

    • 排序: reverse(List), shuffle(List), sort(List), sort(List,Comparator)

    • 查找, 替换: Object max(Collection), Object max(Collection,Comparator), intfrequency(Collection,Object), void copy(List dest,List src), boolean replaceAll()

    • 同步: synchronizedXxx()

泛型 generics

集合中的泛型

public interface List<E> {void add(E x);Iterator<E> iterator();
}

自定义泛型类

class person<T> {// 定义属性private T info;// 定义方法public T getInfo() {return info;}public void setInfo(T info) {this.info = info;}// 定义构造器public Person(T info) {this.info = info;}
}
  • static 方法不能声明泛型
  • try-catch中不能定义泛型
  • 泛型方法

    [访问权限] <泛型> 返回类型 方法名**([泛型标识 参数名称])** 抛出的异常

    public class DAO {public <E> E get(int id, E e) {...}
    }
    

泛型和继承

若B是A的一个子类型(类/接口), G是有泛型声明的类/接口, G<B>不是G<A>子类型

通配符

  • ?, 如 List<?>, Map<?>

  • List<?>List<String>List<Object>等各种泛型List的父类

    • 读取 List<?>中元素是安全的, 因为返回的总是Object
    • 写入 List<?>中元素是不允许的, 除了null, 因为null是所有类型的成员
  • 有限制的通配符

    • <? extends A> 允许泛型为A及A子类的调用
    • <? super A> 允许泛型为A及A父类的调用
    • <? extends Comparable> 允许泛型为实现Comparable接口的实现类的引用调用

枚举 Enum type

  • 枚举类对象的属性不应允许被改动**,** 所以应该使用 private final 修饰

  • enum

    • 必须在枚举类的第一行声明枚举类对象

    • switch-case: case子句直接使用枚举值

    • 主要方法:

      • values() 返回对象数组. 用于遍历所有枚举值
      • valueOf(String str) 把一个字符串转为对应的枚举类对象。要求字符串必须是枚举类对象的“名字”。否则,会有运行异常。
    • 实现接口

      若需要每个枚举值在调用实现的接口方法呈现出不同的行为方式, 则可以让每个枚举值分别来实现该方法

    enum Season implements Info{SPRING("1", "A") {public void show() {sout("a");}},SUMMER("2", "B") {public void show() {sout("b");}},FALL("3", "C"),WINTER("4", "D");
    }
    interface Info {void show();
    }
    

注解 Annotation

  • 内置

    • @Override: 限定重写父类方法, 只能用于方法
    • @Deprecated: 用于表示某个程序元素(类, 方法等)已过时
    • @SuppressWarnings: 抑制编译器警告
  • 自定义

    public @interface MyAnnotation { String str() default "hello";
    }
    
  • 元注解: 修饰其他注解

    Retention
    Target
    Documented
    Inherited

IO

package java.io

File类

File: 文件和目录路径名的抽象表示形式

  • 能新建、删除、重命名文件/目录, 但不能访问文件内容本身。如果需要访问文件内容本身,需使用输入/输出流

  • File对象可以作为参数传递给流的构造函数

  • 方法

    • 访问文件名

      getName()
      getPath()
      getAbsoluteFile()
      getAbsolutePath()
      getParent()
      renameTo(File newName)

    • 文件检测

      exists()

      canWrite()

      canRead()

      isFile()

      isDirectory()

    • 获取文件信息

      lastModified()

      length()

    • 文件操作

      createNewFile()

      delete()

    • 目录操作

      mkDir()

      mkDirs()

      list()

      listFiles()

  • 分类

    • 按操作数据单位 不同分为:字节流(8 bit),字符流(16 bit, 文本)

    • 流向 不同分为:输入流,输出流

    • 角色 的不同分为:节点流(直接处理数据),处理流(加工节点流)

      (抽象基类)字节流字符类
      输入流InputStreamReader
      输出流OutputStreamWriter

      java.io涉及40几个类, 都是从上面4个抽象基类派生的

      派生出的子类名以父类名作为后缀

  • 打开文件IO不属于内存中资源, 无法被自动回收, 应显式关闭IO.

    .close()

节点流

用try-catch处理保证流一定关闭

  • FileInputStream/Reader

    1.建立一个流对象,将已存在的一个文件加载进流。 FileReader fr = new FileReader(“Test.txt”);
    2.创建一个临时存放数据的数组。 char[] ch = new char[1024];
    3.调用流对象的读取方法将流中的数据读入到数组中。 fr.read(ch);

    • int read(byte[] b) int read(char [] c)

    • int read(byte[] b, int offset, int length) int read(char[] b, int offset, int length)

  • FileOutputStream/Writer

    1.创建流对象,建立数据存放文件 FileWriter fw = new FileWriter(“Test.txt”);
    2.调用流对象的写入方法,将数据写入流 fw.write(“text”);
    3.关闭流资源,并将流中的数据清空到文件中 fw.close();

    • void write(byte[] b/char[] cbuf)
    • void write(byte[] b/char[] buff, int offset, int length)
    • void write(String str) void write(String str, int off, int len)

缓冲流

  • 在使用缓冲流类时,会创建一个内部缓冲区数组

  • 缓冲流要“套接”在相应的节点流之上,提高了读写的效率,增加了一些新方法

  • BufferedInputStream/Reader

    • BufferedReader br.readline() 一次读一行
  • BufferedOutputStream/Writer

    • 每次写入后刷新缓冲区 flush()

    20200522-2T89qF

转换流

  • 在字节流和字符流之间 按指定字符集转换
  • 同样要套接在相应节点流上
  • InputStreamReader和OutputStreamWriter

标准输入输出流

  • System.in和System.out分别代表系统标准的输入和输出设备. 默认输入设备是键盘,输出设备是显示器

  • System.in的类型是InputStream System.out的类型是PrintStream, 是OutputStream的子

    类FilterOutputStream的子类

  • 通过System类的setIn(),setOut()对默认设备进行改变

打印流

  • PrintStream(字节打印流)和PrintWriter(字符打印流)

数据流

  • 处理基本数据类型, String, DataInputStream 和 DataOutputStream

对象流

  • ObjectInputStream和OjbectOutputSteam

  • 存储和读取对象的处理流

  • 序列化(Serialize):用ObjectOutputStream类将一个Java对象 写入IO流中
    反序列化(Deserialize):用ObjectInputStream类从IO流中恢复该Java对象
    ObjectOutputStream和ObjectInputStream不能序列化statictransient修饰的成员变量

  • 类及属性都要实现Serializable接口才能序列化

  • 实现Serializable接口的类都有一个表示序列化版本标识符的静态变量: private static final long serialVersionUID

    • 应显示定义.

      如果类没有显示定义这个静态变量,它的值是Java运行时自动生成。若类的源代码作了修改,serialVersionUID可能发生变化

    • 用途: 类的不同版本间的兼容性

RandomAccessFile

跳到文件的任意地方来读、写文件

  • RandomAccessFile对象包含一个记录指针,用以标示当前读, 写处的位置。RandomAccessFile 类对象可以自由移动记录指针:
    long getFilePointer(): 获取文件记录指针的当前位置

    void seek(long pos): 将文件记录指针定位到 pos 位置

  • 构造器
    public RandomAccessFile(String name, String mode)

    • mode 指定 RandomAccessFile 的访问模式:

      r: 以只读方式打开
      rw:打开以便读取和写入
      ➢ **rwd:**打开以便读取和写入;同步文件内容的更新
      ➢ **rws:**打开以便读取和写入;同步文件内容和元数据的更新

多线程

java.lang.Thread类

创建线程第一种方法: 继承Thread类

  1. 定义子类继承Thread类。
  2. 子类中重写Thread类中的run方法。
  3. 创建Thread子类对象,即创建了线程对象。
  4. 调用线程对象start方法:启动线程,调用run方法。

20200523-Zkyuv3

Thread 常用方法

  • void start(): 启动线程,并执行对象的run()方法

  • run(): 线程在被调度时执行的操作

  • String getName(): 返回线程的名称

  • void setName(String name):设置该线程名称

  • static currentThread(): 返回当前线程

  • static void yield(): 暂停当前正在执行的线程,把执行机会让给优先级相同或更高的线程

  • join() :当某个程序执行流中调用其他线程的 join() 方法时, 调用线程将被阻塞,直到 join() 方法加入的 join 线程执行完为止

  • static void sleep(long millis):(指定时间:毫秒) 令当前活动线程在指定时间段内放弃对CPU控制,使其他线程有机会被执行,时间到后重排队。

  • 线程的优先级控制
    MAX_PRIORITY(10); MIN _PRIORITY (1); NORM_PRIORITY (5);

    • 线程创建时继承父线程的优先级

    方法:

    • getPriority() :返回线程优先值
    • setPriority(int newPriority) :改变线程的优先级

java.lang.Runnable接口

创建线程第二种方法: 实现Runnable接口. 更好

  1. 定义子类,实现Runnable接口。
  2. 子类中重写Runnable的run()
  3. 通过Thread类含参构造器创建线程对象
  4. 将Runnable的子类对象作为实际参数传递给Thread类的构造方法中
  5. 调用Thread类的start():开启线程,调用run()
class PrimeRun implements Runnable {long minPrime;PrimeRun(long minPrime) {this.minPrime = minPrime;}public void run() {. . .}
}PrimeRun p = new PrimeRun(143);
new Thread(p).start();

线程的生命周期

20200523-KJoiD5

线程的同步

  • 提出的问题:

    多个线程操作共享数据可能出现一个线程未执行完毕时, 另外的线程参与进来而破坏数据。

  • 解决办法**😗*

    对多条操作共享数据的语句,只能让一个线程都执行完,在执行过程中, 其他线程不可以参与执行。

    • 同步代码块

      所有线程必须共用同一把锁; 包裹的代码块不多也不少, 只有共享数据的部分

      // 可以用任意一个类的对象充当同步监视器(锁)
      Object obj = new Object();
      public void run() {// Object obj = new Object(); 这样会导致每个线程自己有一把锁, 没有同步的作用synchronized(obj) {// 需要被同步的代码}
      }
      
    • 同步方法

      同步方法(非静态的)的锁为this。
      同步方法(静态的)的锁为当前类本身。

      public synchronized void show (String name){...}
      

    互斥锁 mutex

    防止两条线程同时对同一公共资源进行读写的机制

    • 释放锁:

      • 当前线程的同步方法/代码块执行结束; 被break, return终止; 异常抛出
      • 当前线程的同步方法/代码块执行wait(), 暂停当前线程, 并释放锁
    • 不会释放锁:

      • 遇到sleep(), yield()暂停当前线程
    • 死锁

      不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死锁.

      减少同步资源的定义.

线程通信

java.lang.Object

  • wait() 令当前线程挂起并放弃CPU、同步资源,使别的线程可访问并修改共享资源,而当前线程排队等候再次对资源的访问
  • notify():唤醒正在排队等待同步资源的线程中优先级最高者
  • notifyAll():唤醒正在排队等待资源的所有线程

这三个方法只有在synchronized方法或代码块中使用,否则会报 java.lang.IllegalMonitorStateException异常

常用类

String类

  • 使用Unicode字符编码,一个字符占两个字节
  • String是一个final类,代表不可变的字符序列. 底层实现是char[]

20200525-tVoKkl

常量池理解

  • 字符串对象操作

    • public int length()
    • public char charAt(int index)
    • public boolean equals(Object anObject)
    • public int compareTo(String anotherString)
    • public int indexOf(String s)
    • public int indexOf(String s ,int startpoint)
    • public int lastIndexOf(String s)
    • public int lastIndexOf(String s ,int startpoint)
    • public boolean startsWith(String prefix)
    • public boolean endsWith(String suffix)
    • public boolean regionMatches(int toffset, String other, int ooffset, int len)
  • 字符串对象修改

    • public String substring(int startpoint)

    • public String substring(int start,int end)

    • pubic String replace(char oldChar,char newChar)

    • public String replaceAll(String old,String new)

    • public String trim()

    • public String concat(String str)

    • public String[] split(String regex)

  • 包装类, 基本数据类型, 字节/字符数组 相互转换

    1. 字符串 与 基本数据类型, 包装类 转换

      • 字符串 -> 基本数据类型/包装类: 包装类的parseXxx(String str)
      • 基本数据类型/包装类 -> 字符串: 字符串重载的valueOf()
    2. 字符串 与 字节数组 转换

      • 字符串 -> 字节数组: 字符串的getBytes()

      • 字节数组 -> 字符串: 字符串的构造器

    3. 字符串 与 字符数组 转换

      • 字符串 -> 字符数组: 字符串的toCharArray()
      • 字符数组 -> 字符串: 字符串的构造器

StringBuffer

java.lang.StringBuffer代表可变的字符序列,可以对字符串内容进行增删改查. 线程安全.

添加 append()

删除 delete(int start, int end)

修改 setCharAt(int index, char ch)

插入 insert()

反转 reverse()

长度 length()

StringBuilder

java.lang.StringBuilder和StringBuilder类似, 效率更高, 但线程不安全

日期类

  • java.lang.System类下的public static long currentTimeMillis(), 用于计算时间差

  • java.util.Date (及其子类 java.sql.Date)

    • toString()
    • getTime()
  • java.text.SimpleDateFormat

    不与语言环境有关的方式来格式化和解析日期的具体类.

    格式化(日期->文本)、解析(文本->日期)

  • java.util.Calendar

    抽象基类,主用用于完成日期字段之间相互操作的功能

    • 获取Calendar实例的方法

      • 使用Calendar.getInstance()方法
      • 调用它的子类GregorianCalendar的构造器
    • get(), add(), Date getTime()/setTime(Date d)

Math类

java.lang.Math提供了一系列静态方法用于科学计算;其方法的参数和返回值类型一般为double型

BigInteger/BigDecimal

支持任意精度

反射

**Reflection(反射)**是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息且能直接操作.

Class类

  • java.lang.Class 本身是一个类
  • 一个类在JVM中只有一个Class对象, 因为只能创建一次
  • 一个Class对象对应一个加载到JVM的一个.class文件
  • 通过Class可以完整得到一个类的结构

获取Class类的对象

  1. 若已知具体的类,通过类的class属性获取,该方法最安全可靠,性能最高

    Class clazz = String.class;
    
  2. 已知某个类的实例,调用该实例的getClass()方法获取Class对象

    Class clazz = “hello, world”.getClass(); 
    
  3. 已知一个类的全类名,且该类在类路径下,可通过 Class类的静态方法forName() 获取,可能抛ClassNotFoundException

    Class clazz = Class.forName(“java.lang.String”);
    
  4. 类的加载器(了解)

    ClassLoader cl = this.getClass().getClassLoader(); 
    Class clazz4 = cl.loadClass(“类的全类名”);
    

    getResourceAsStream(String str):获取类路径下的指定文件的输入流

创建类对象并获取其完整结构

  • 创建类的对象

    1. 调用Class对象的newInstance()
      • 类必须要有一个无参的构造器
      • 类的构造器访问权限足够
    2. 若类没有无参构造器, 则先取得指定形参的构造器, 显式调用, 再实例化
  • 获取对应的运行时类的属性

    • Field[] getFields() 获取类中及其父类中声明为public的属性
    • Field[] getDeclaredFields() 获取类本身声明的所有属性
      • int getModifiers() 以整数形式返回此Field的修饰符
      • Class<?> getType() 得到属性类型
      • String getName() 返回属性名
  • 获取对应的运行时类的方法

    • Method[] getMethods() 返回类或接口本身的public的方法
    • Method[] getDeclaredMethods() 返回类及父类的全部方法
      • Class<?> getReturnType()取得全部的返回值
      • Class<?>[] getParameterTypes() 取得全部的参数
      • int getModifiers()取得修饰符
      • Class<?>[] getExceptionTypes() 取得异常信息
  • 构造器

    • public Constructor<T>[] getConstructors()
      返回类的所有public构造方法
    • public Constructor<T>[] getDeclaredConstructors()
      返回此类声明的所有构造方法。
      • 取得修饰符: public int getModifiers()
      • 取得方法名称: public String getName()
      • 取得参数的类型: public Class<?>[] getParameterTypes()
  • 注解

    getAnnotation(Class<T> annotationClass)
    getDeclaredAnnotations()

  • 泛型

    • 获取父类泛型类型:Type getGenericSuperclass()
    • 泛型类型: ParameterizedType
    • 获取实际的泛型类型参数数组: getActualTypeArguments()
  • Package getPackage()

调用指定属性, 方法, 构造器

  • 属性

    • public Field getField(String name) 返回public的属性名为name的属性。
      public Field getDeclaredField(String name) 返回属性名为name的属性。

    • public Object get(Object obj) 取得指定对象obj上此Field的属性内容
      public void set(Object obj,Object value) 设置指定对象obj上此Field的属性内

      当类中属性设置为private,在使用set()和get()方法时,首先要使用Field类中的setAccessible(true)方法将需要操作的属性设置为可以被外部访问

  • 方法

    1. 通过Class类的getMethod(String name,Class...parameterTypes)方法取得一个Method对象,并设置此方法操作时所需要的参数类型。

    2. 调用Class.newInstance()

    3. 若原方法声明为private,则需要在调用invoke()方法前, 显式调用方法对象setAccessible(true)方法,将可访问 private的方法。

    4. 之后使用Object invoke(Object obj, Object[] args)进行调用,并向方法中传递要设置的obj对象的参数信息。

动态代理

  • 代理模式: 使用一个代理将对象包装起来, 然后用该代理对象取代原始对象. 任何对原始对象的调用都要通过代理. 代理对象决定是否以及何时将方法调用转到原始对象

  • 动态代理步骤

    1. 创建被代理的类, 接口
    2. 创建一个实现接口InvocationHandler的类,必须实现invoke方法,以完成代理的具体操
    3. 通过Proxy类的静态方法Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) 创建一个代理类对象
    4. 当通过代理类对象发起对被重写的方法调用时, 会转换为invoke()调用
  • AOP (Aspect Orient Programming)

    20200528-9cyVe4

    20200528-qk349Y

网络编程

网络基础

  • 如何实现网络中主机互相通信

    • 通信双方地址

    • 数据传输的规则: OSI模型, TCP/IP协议

      20200528-ACK9ib

  • IP, 端口号

    • IP

      • 域名-(DNS)->IP

      • java.net.InetAddress类

        没有公共构造器, 提供2个静态方法获取实例:

        getByName(String host)

        getByAddress(byte[] addr)

    • 端口号: 进程

      16位整数 0-65535. 其中0-1023被预先定义占用.

  • 网络通信协议

    • TCP(Transmission Control Protocol)
      使用TCP协议前,须先采用“三次握手”方式建立连接
      在连接中可进行大数据量的传输
      传输完毕,需释放已建立的连接,“四次挥手”

      可靠但效率低

    • UDP(User Datagram Protocol)

      将数据、源、目的封装成数据包,不需要建立连接

      每个数据报的大小限制在64K内

      因无需连接,故是不可靠的

      发送数据结束时无需释放资源,速度快

  • Socket 套接字

    • 通信的两端都要有Socket,是两台机器间通信的端点
    • Socket允许程序把网络连接当成一个流,数据在两个Socket间通过IO传输。
    • 一般主动发起通信的应用程序是客户端,等待通信请求的为服务端

    当server使用阻塞IO(如InputStream.read()), 在数据没有到达前,read 会挂起,进程会卡住. 需要client在发送完数据后, 显式告诉server发送完毕(void shutdownOutput())

  • UDP通信

    1. DatagramSocket与DatagramPacket

      UDP数据报通过数据报套接字DatagramSocket发送和接收,

      DatagramPacket对象封装了UDP数据报,在数据报中包含了发送端的IP地址和端口号以及接收端的IP地址和端口号

    2. 建立发送端,接收端

    3. 建立数据包

    4. 调用Socket的发送、接收方法

    5. 关闭Socket

  • URL编程

    java.net.URL类

    • URL的方法 InputStream openStream():能从网络上读取数据
    • URLConnection: 要发送数据, 则先建立连接. 通过URLConnection openConnection()生成URLConnection对象

这篇关于三个月呕心巨制!Java必备知识点的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/550941

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

基本知识点

1、c++的输入加上ios::sync_with_stdio(false);  等价于 c的输入,读取速度会加快(但是在字符串的题里面和容易出现问题) 2、lower_bound()和upper_bound() iterator lower_bound( const key_type &key ): 返回一个迭代器,指向键值>= key的第一个元素。 iterator upper_bou

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听