JavaCoreⅠ

Java Core Ⅰ

[TOC]

第一章

void function(显式参数){

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

}

第二章

javac是java编译器

Jshell

第三章

java没有无符号形式

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

类常量定义在main方法外部

byte最大值为256

位运算符

编译器可以让字符串共享

String

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

在这里插入图片描述

StringBuffer

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

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

  在看一下b对象的内存空间图: 在这里插入图片描述

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

StringBuilder  

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

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

StringBuffer类中实现的方法:

在这里插入图片描述

StringBuilder类中实现的方法:

在这里插入图片描述

  由此可见,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

数组可以交换行

命令行参数

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

第四章

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

var

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

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

Java方法参数采用按值调用

重载:不同签名等的方法

默认字段初始化

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

第五章

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

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

public class Main {
    public static void main(String[] args) {
        B o1 = new C();
        o1.f(3);
    }
}
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");
    }
}
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");
    }
}
# 运行结果
f(double 3.0)B
g(double 3.0)C

原理

编译时类型和运行时类型,例如:

Person person = new Student();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

//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. 使用多态,而不要使用类型信息

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

第六章

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

Last updated