# JavaCoreⅠ

## **Java Core Ⅰ**

\[TOC]

## 第一章

```java
void function(显式参数){

​	name = ---;//name 隐式参数

}
```

## **第二章**

javac是java编译器

Jshell

## **第三章**

java没有无符号形式

final变量表示只能被赋值一次 通常使用全大写

类常量定义在main方法外部

byte最大值为256

位运算符

编译器可以让字符串共享

### String

String类是不可变类，即一旦一个String对象被创建以后，包含在这个对象中的字符序列是不可改变的，直至这个对 象被销毁。

![在这里插入图片描述](https://raw.githubusercontent.com/EddeCode/my-pic/main/202211261208183.png)

#### StringBuffer

  StringBuffer对象则代表一个字符序列可变的字符串，当一个StringBuffer被创建以后，通过StringBuffer提供的append()、insert()、reverse()、setCharAt()、setLength()等方法可以改变这个字符串对象的字符序列。一旦通过StringBuffer生成了最终想要的字符串，就可以调用它的toString()方法将其转换为一个String对象。

```java
StringBuffer b = new StringBuffer("123");
b.append("456");
// b打印结果为：123456
System.out.println(b);
1234
```

  在看一下**b对象的内存空间图：** ![在这里插入图片描述](https://raw.githubusercontent.com/EddeCode/my-pic/main/202211261208736.png)

所以说StringBuffer对象是一个字符序列可变的字符串，它没有重新生成一个对象，而且在原来的对象中可以连接新的字符串。

#### StringBuilder  

StringBuilder类也代表可变字符串对象。实际上，StringBuilder和StringBuffer基本相似，两个类的构造器和方法也基本相同。不同的是：**StringBuffer是线程安全的，而StringBuilder则没有实现线程安全功能，所以性能略高。**

**StringBuffer是如何实现线程安全的呢？**

StringBuffer类中实现的方法：

![在这里插入图片描述](https://raw.githubusercontent.com/EddeCode/my-pic/main/202211261208776.png)

StringBuilder类中实现的方法：

![在这里插入图片描述](https://raw.githubusercontent.com/EddeCode/my-pic/main/202211252312973.png)

  由此可见，StringBuffer类中的方法都添加了**synchronized关键字**，也就是给这个方法添加了一个锁，用来保证线程安全。

**Java9的改进**

  Java9改进了字符串（包括String、StringBuffer、StringBuilder）的实现。在Java9以前字符串采用char\[]数组来保存字符，因此字符串的每个字符占2字节；而Java9的字符串采用byte\[]数组再加一个encoding-flag字段来保存字符，因此字符串的每个字符只占1字节。所以Java9的字符串更加节省空间，字符串的功能方法也没有受到影响。

### Arrays

P85

* Arrays.copyof(源数组,新数组长度)
* Arrays.sort()//数组排序
* Arrays.euqals()//位置和元素都相等返回true
* Arrays.toString()//格式化遍历数组
* Arrays.deepToString()//打印二维数组
* Arrays.hashCode(xxx\[] a)//计算数组a的散列

大数 BigInteger BigDecimal

数组可以交换行

命令行参数

```shell
java Message -h world // String[] args : args[0]="-h" args[1]="world"
```

## 第四章

使用clone方法获取对象完整副本

var

方法可以访问所属类任何对象的私有特性

静态方法不能访问实例字段

Java方法参数采用按值调用

重载:不同签名等的方法

默认字段初始化

对象初始化块 构造在这个类的对象时就会被**执行**

## 第五章

### 多态-编译时对象和运行时对象

有B类以及B的子类C,会出现先调用B的方法又去调用C的方法的现象，既父类调用了子类的方法。

```java
public class Main {
    public static void main(String[] args) {
        B o1 = new C();
        o1.f(3);
    }
}
```

```java
public class B {
    public B() {
    }

    public void f(double d) {
        System.out.println("f(double " + d + ")B");
        this.g(d);
    }

    public void g(int i) {
        System.out.println("g(int " + i + ")B");
    }

    public void g(double d) {
        System.out.println("g(double " + d + ")B");
    }
}
```

```java
public class C extends B {
    public C() {
    }

    public void f(int i) {
        System.out.println("f(int " + i + ")C");
        this.g(i);
    }

    public void g(double d) {
        System.out.println("g(double " + d + ")C");
    }
}
```

```java
# 运行结果
f(double 3.0)B
g(double 3.0)C
```

#### 原理

编译时类型和运行时类型，例如：

```java
Person person = new Student();
```

这行代码将会生成一个person变量，该变量的编译时类型是Person，运行时类型是Student。

**说明一下编译时类型和运行时类型：**

Java的引用变量有两个类型，一个是编译时类型，一个是运行时类型，编译时类型由声明该变量时使用的类型决定，运行时类型由实际赋给该变量的对象决定。

如果编译时类型和运行时类型不一致，会出现所谓的多态。因为子类其实是一种特殊的父类，因此java允许把一个子类对象直接赋值给一个父类引用变量，无须任何类型转换，或者被称为向上转型，由系统自动完成。

引用变量在编译阶段只能调用其编译时类型所具有的方法，但运行时则执行它运行时类型所具有的方法，

因此，编写Java代码时，引用变量只能调用声明该变量所用类里包含的方法。

与方法不同的是，对象的属性则不具备多态性。通过引用变量来访问其包含的实例属性时，

系统总是试图访问它编译时类所定义的属性，而不是它运行时所定义的属性。

◾ 内部类可以私有 外部类不可以也没有意义

◾ 子类构造器初始化超类私有字段 子类构造器第一行使用super

```java
var boss = new Manager();
Employee staff = boss;
boss.setBouns(5000);//Manager特有方法
staff.setBouns(5000);//ERROR
Manager m = new Employee();//ERROR可以强制类型转换编译但不能运行
```

◾ 编译器容许参数类型转换

```java
Void f(double x){
    reutrn x;
}
f(1);
```

◾ 允许子类将覆盖的方法的返回类型改为源返回类型的子类型，即：**可协变的返回类型**

```java
//Example1:int没有子类型，只能为int
public int function(){...}//super method
//
public int function(){...}//extends super

//Example2:
public Employee getBuddy(){...}//super method
//
public Manager getBuddy(){...}//extends super
```

◾ 子类方法不能低于超类方法的可见性（权限）

◾ final：阻止继承，如果一个类为final，方法自动为final，不包括字段

◾ 可以向上转型，不能向下转型；instanceof可以实现检查能否转换成功

### 抽象类

抽象方法只能定义在抽象类中

可以定义抽象类的对象变量，但不能实例化抽象方法

### protected 受访问保护

1. 希望某个方法只允许子类访问
2. 保护字段只由同一包中的类访问

不写访问控制修饰符（默认）：仅对本包可见

### Object

相等测试与继承：equals设计原则（p176）

@override标记该方法要覆盖超类的方法

hashcode方法

### **Class类getSuperClass()方法**

* getSuperClass()方法在java.lang包中可用。
* getSuperClass()方法用于返回Class，该Class表示此Class表示的任何类，接口，原始类型或任何void类型的超类。
* getSuperClass()方法是一个非静态方法，只能通过类对象访问，如果尝试使用类名称访问该方法，则会收到错误消息。getSuperClass()方法在返回超类时不会引发异常。

### ArrayList

​ ensureCapacity()//提前确定容量，避免反复扩容带来的开销

​ trimToSize()//削减为当前元素所需要的空间

### 对象包装器与自动装箱

* 自动装箱规范要求boolean，byte，char<=127,介于-128和127之间的short和int被包装到固定的对象中
* 装箱和拆箱时编译器的工作

​ **Integer**

* int intValue()
* static Integer valueOf()//返回新的Integer对象，转换进制显示

### 枚举类

枚举类的构造器总是私有的

里面声明实例

### 反射

**class类**

虚拟机为每个类型管理一个唯一的class对象，可以用==对比

**API**

* static Class forName(String className)//返回一个名对应的Class对象
* p207 208 212 213

### 继承的设计技巧

1. 将公共操作和字段放在超类
2. 不要使用受保护的字段
3. 使用继承实现is-A关系
4. 除非所有继承的方法都有愿意，否则就不要使用继承
5. 在覆盖原方法是不要改变预习行为
6. 使用多态，而不要使用类型信息

   ```java
   type1 type2 extend type0
   if(x is of type1)
       action1(x);
   else if(x is of type2)
       action2(x);
   //应该使用多态
   type0 x;
   x.action();    
   ```
7. 不要滥用反射

## 第六章

```java
public interface MyInterface {
    static final int size0 = 5;
    public   	static final int size1 = 5;
    private  	static final int size2 = 5;//error
    protected  	static final int size3 = 5;//error
    String tips ="Illegal modifier for the interface field MyInterface.size2(3); only public, static & final are permitted";
}
```

## 第十二章

**一、线程池的体系结构：**

​

Executor 负责线程的使用和调度的 根接口

\|-- ExecutorService 接口： 线程池的主要接口。增加了返回Future 对象

​ |-- ThreadPoolExecutor 线程池的实现类

​ |-- SchduledExceutorService 接口： 负责线程的调度

​ |-- ScheduledThreadPoolExecutor ： 继承ThreadPoolExecutor，实现了ScheduledExecutorService
