王道Java40th笔记


目录
  • 0322
      • 全限定类名
      • 转义字符
      • 默认初始化值
      • nextLine( ) 后面不要使用 next*( )
  • 0323
      • 内存分布
      • 设计模式(单例)
      • 类的成员
      • final 修饰符
      • 内部类
        • 局部内部类
        • 匿名内部类
  • 0324
      • foreach
      • Java仅有值传递
  • 0325
      • this
      • 类加载
  • 0326
      • 静态成员变量和成员变量的赋值
      • 枚举
      • 重载&重写&多态
      • == 和 equals( ) 的区别
  • 0327
      • 注解
  • 0328
      • Random 特性
      • 代码块
      • 访问权限修饰符
      • 包装类
        • 优先级提升
  • 0329
      • 继承的特性
      • 子类重写的限制
      • 重写 & 重载
      • 多态
      • 引用类型转换
      • Super
      • Final
  • 0330
      • Object

0322


全限定类名

包含包名的方法名全称;防止因为类名重复,编译器就近原则选择错方法

转义字符

/b 退格

/t Tab

默认初始化值

基本数据类型作为 [类成员] 的时候,即使没有进行初始化。Java也会给定默认的初始值

boolean false

char '/uoooo'(null)

byte (byte)0

short (short)0

int 0

long 0L

float 0.0f

double 0.0d

引用 null

局部变量没有默认值,需要依靠手动初始化

nextLine( ) 后面不要使用 next*( )

会导致输入异常

0323


内存分布

基本数据类型---栈帧
引用数据类型---栈帧(引用)+堆(对象)
栈---局部变量---没有默认值,需要初始化才可用
堆---存储对象---在初始化前就有了默认值(即使指定赋值非空,也先赋默认值null,再赋指定值)

类的 成员变量--堆的对象中

?	局部变量--方法的栈帧内

设计模式(单例)

目的:使得一个类,只能创建一个对象

实现:私有化构造方法 --> 在类内静态实例化 --> 提供获取静态实例的公有方法

// 饿汉式:加载就实例化,可能浪费资源
public class Day3MyDemo {

    private int id;
    private String name;
    // 创建私有化静态(保证唯一性)对象实例
    private static Day3MyDemo d3 = new Day3MyDemo(1, "张三");
    // 私有化构造方法,防止类外new新的对象
    private Day3MyDemo(int id, String name) {
        this.id = id;
        this.name = name;
    }
    // 外部获取对象的方式
    public static Day3MyDemo getInstance(){
        return d3;
    }
}
// 懒汉式:使用时才实例化,存在线程安全问题
public class Day3MyDemo {

    private int id;
    private String name;
    // 私有化构造方法,防止类外new新的对象
    private Day3MyDemo(int id, String name) {
        this.id = id;
        this.name = name;
    }
    // 只声明,不实例化
    private static Day3MyDemo day3MyDemo = null;
    // 需要用时才实例化,多线程存在线程安全问题
    public static Day3MyDemo getInstance(){
        if (day3MyDemo == null){
            day3MyDemo = new Day3MyDemo(1,"张三");
     	}
     	return day3MyDemo;
	}
}

类的成员

属性,方法,构造器,代码块,内部类

final 修饰符

不想被继承,覆盖,重写,修改 时使用

内部类

局部内部类

  1. 定义在方法中/代码块中,作用域也是方法中/代码块中
  2. 本质是一个类
  3. 不能加访问修饰符,可以final限定
  4. 内部可直接访问外部类所有成员,重名遵循就近原则(包括private)-- E.g 外部类名.this.mathod( )
  5. 外部类访问内部类,要实例化再访问
  6. 外部其他类(非包含该内部类的类)不能访问
class Outer {
    private int a;
    public Outer(int a) {
        this.a = a;
        System.out.println("Outer Constructer");
    }

    private void mathod1() {
        System.out.println("Outer mathod1()");
    }

    public void mathod2() {
        System.out.println("Outer mathod2()");
        // 方法内部的局部内部类
        class Inner {
            private int a;
            public Inner(int a) {
                this.a = a;
                System.out.println("Inner Constructer");
            }

            public void mathod3() {
                System.out.println("Inner mathod3()");
                System.out.println("访问a默认就近原则,a = " + a);
                System.out.println("访问Outer的私有成员 a = " + Outer.this.a);
                Outer.this.mathod1();//可以访问外部类的私有方法
            }
        }
        // 仅能在mathod2内使用Inner
        Inner in1 = new Inner(666);
        in1.mathod3();
    }
}

匿名内部类

  1. 定义在外部类的局部位置,如方法中,作用域在定义的方法/代码块中
  2. 本质是类,但是没有类名,也不能加访问修饰符
  3. 也是一个对象,因此可以作为传入方法的实参
  4. 可直接访问外部类所有成员,重名遵循就近原则
  5. 外部其他类(非包含该内部类的类)不能访问

0324


foreach

for(ElemType et:容器名)

Java仅有值传递

  1. 值传递(call by value),指的是方法接收的不是实参本身,而是实参一个拷贝;因此方法是不能对实参做出修改的
  2. 引用传递(call by reference) ,指的是方法接收就是实参本身(实参的地址),不是拷贝对象,方法是可以对实参做出修改
  3. 实参是局部变量,那么方法不能对另外一个方法中的局部变量做任何修改。这个局部变量包括: 基本数据类型变量,引用数据类型的引用,实际上,Java肯定不可能存在引用传递,一旦有引用传递,局部变量就会在方法外部生效(局部变量就不"局部"了)
  4. 方法可以通过获取--引用数据类型的引用--的值拷贝,进而去访问原先引用所指向的对象那么就可以修改对象中元素的取值(称之为修改对象的状态);但是值拷贝的交换,不能对两个实参进行交换。

0325


this

Student s = new Student();

s.name() 成员方法的隐含形参this,默认传递引用s作为实参

静态成员方法不含 this 如果调用成员方法,需要手动对象实例化

类中 this(参数1,参数2,...) 表示调用对应参数的构造器,仅能够在构造器内的 第一行调用一次super 同样

类加载

  • 过程:加载 --> 连接 --> 初始化
  • 在创建对象 new 前,会类加载(类加载的一部分【加载,连接】)
  • 访问类的静态成员 类名.静态成员 前,会类加载
  • 启动 main 方法前也会对main所在的类进行类加载
  • 子类 的类加载会触发 父类 的类加载;先父后子
    • 子类名.父类静态成员 不进行子类的类加载
    • 创建子类对象时,不会连带创建父类对象,父类的成员会创建在子类对象(堆)的专门区域里, super 指向这块区域
  • 类加载 仅加载一次 ,无论之后是否创建对象,调用方法,都不会再进行类加载
  • 类加载,执行带有 static 的语句和代码块,连接时对静态成员初始化,与显示初始化语句无关
  • 基本数据类型 和 String 的 全局常量static final 调用不触发类加载(不在类的静态常量池中)

构造器

赋值顺序:默认值赋值--> 显示初始值赋值 --> 构造器形参赋值

0326


静态成员变量和成员变量的赋值

  1. 静态成员变量在类加载时初始化(默认赋值 --> 显示赋值)
  2. 成员变量在创建对象时赋值
  3. 类加载先于对象的创建,因此静态成员初始化早于成员变量
  4. 赋值顺序都是:默认值赋值--> 显示赋值 --> 构造器赋值
  5. 构造代码块赋值 与 显示赋值 顺序执行

枚举

适用场景:希望一个类里面只能创建特定的对象(一组有限的,不能随意定义)

public class Enum {

    public static void main(String[] args) {
        System.out.println(Season.SPRING);
    }
}

enum Season{

/* 等价于 public static final Season SPRING = new Season("spring","cool");
* 规则:1.必须定义在类的最前面
*	   2.多个常量由 逗号 隔开
*	   3.调用无参构造器可省略()
*/ 
    SPRING("spring","cool"),
    WINTER("winter","cold"),
    // 调用无参构造器可省略()
    AUTUMN;

    private String name;
    private String feel;

    Season() {}

    Season(String name, String feel) {
        this.name = name;
        this.feel = feel;
    }

    @Override
    public String toString() {
        return "Season{" +
                "name='" + name + '\'' +
                ", feel='" + feel + '\'' +
                '}';
    }
}

重载&重写&多态

  • 重载 就是多个同样名的方法,能够根据输入数据的不同,做出不同的处理

  • 重写 就是当子类继承自父类时,子类父类含有同名方法,子类覆盖父类的同名方法

  • 多态 即一个对象具有多种的状态,当父类的引用指向子类的实例时,如果子类重写了父类的方法,真正执行的是子类的方法,如果子类没有覆盖父类的方法,执行的是父类的方法,如果只在子类存在但在父类不存在的方法,不能调用

== 和 equals( ) 的区别

  • 对于基本数据类型来说,== 比较的是值

  • 对于引用数据类型来说,== 比较的是引用,即对象的内存地址

  • Object.equals() 方法等价于 == 是比较的对象的内存地址

  • String.equals() 重写了Object.equeal()方法,比较的是对象,即内存中存放的内容;

0327


注解

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

0328


Random 特性

左闭右开[ )

代码块

  • 构造代码块:在构造器调用时执行;在显示赋值,构造代码块同时存在时--顺序执行(不能使用this调用构造器)
  • 构造代码块仅可以给成员变量赋值,块内定义的变量是局部变量,不是成员
  • 构造代码块:类加载不执行,new执行
  • 构造代码块应用:提取出构造器需要公共执行的方法写入构造代码块 -- 编译自动添加到每个构造器中
  • 静态代码块:在类加载时执行
  • 静态代码块应用:用于给类的静态成员赋值,包含仅执行一次的方法,测试类加载

访问权限修饰符

  • 一般限定类内成员
  1. private -- 只能够在同一类中能够访问,私有的,外面谁都不能用。
  2. 默认(缺省) -- 同一包中的子类或者其它类能够访问,同包中都可以使用。
  3. protected -- 不同包的子类能够通过创建 子类对象 访问父类,同包可任意访问。
    • 不同包的子类,只有创建 子类自身对象 ,才可以访问父类成员
    • 目的:防止滥用,仅仅提供给子类使用
  4. public -- 不同包的其他类能够访问。

包装类

image-20220328222040930

image-20220328222135301

优先级提升

// 三元运算符为一个整体,混合运算优先级以最高的为准
Object obj = true?new Integer(1):new Double(2);
System.out.println(obj); // 1.0 Integer --> Double

0329


继承的特性

  1. 关系:子类 is-a 父类

  2. 子类名.父类静态方法 访问父类静态方法

  3. 子类的类加载会触发父类的类加载,并且类加载的顺序是 先父后子

  4. 类对象创建的过程中,父类的构造方法会被调用,但是不会创建父类的对象

    子类构造器隐含 super();

  5. 子类对象中会专门开辟一片独立的区域,用来存储父类的成员变量

  6. superthis 两个关键字在表示调用构造器时,不能共存

  7. 子类含有父类同名成员,父类同名成员会被隐藏,可用 super 调用

  8. 静态成员变量,没有继承关系;父子类同名静态成员有各自的存储空间,互补干涉

  9. 默认直接继承Object ,一旦手动继承了其他类,则变成了间接继承了Object 即继承类直接继承Object (如果继承类没有显示继承其他类的时)

  10. 子类 与 父类 有同名成员变量 父类变量被隐藏,有同名成员方法 父类方法被覆盖;但都可以使用super来调用

    • 对象名.成员变量 的范围和值,都由引用的数据类型来决定,因为编译器只能看引用,对象要在创建时进行类加载才可显示
    • 对象名.方法名 的范围和调用结果,是根据 new 对象的实际类型 来决定的

子类重写的限制

  1. 保持一致 : 方法名,形参列表
  2. 保持兼容:访问权限等级,返回值类型

重写 & 重载

方法重载Overload 方法重写Override
同类中 父子类
方法名 相同 相同
参数列表 不同 相同
访问权限 不影响 子类方法的访问权限 >= 父类访问权限
返回类型 不影响 子类方法返回值类型保持兼容

构造方法,静态方法,私有方法,final方法--不能重写

多态

  • 条件:存在继承,方法重写,父类引用指向子类对象
  • 特征:父类引用,指向不同子类,不同子类重写了同名方法,调用产生不同效果
  • 区分:父子类存在同名成员变量,表现出属性的隐藏

引用类型转换

  1. 引用类型的类型转换,转换的是 引用 ,不是对象

  2. 向上转型--自动;向下转型--手动强转

    • 需要使用 instanceof 关键字判断,保障向下转型安全性

Super

  • 不是引用,指向子类对象的一片特殊区域

Final

  • 修饰的类不能被继承

  • 修饰的方法不能被重写,但所在类可以被继承

  • 修饰的变量是基本数据类型则值不能改变 -- 常量;如果是成员变量,则没有了默认赋值,需要手动赋值(显示赋值/构造代码块/构造器),如果使用构造器赋值,则要保证所有构造器都能给final成员变量赋值

  • 修饰的变量是引用类型则不能再指向其他对象

0330


Object

  1. getClass()
    • 获取Class对象,这个对象是JVM在类加载时创建的
    • 同一个类运行时Class对象在内存中,只有唯一一个;不同类的Class对象必然不是同一个对象
    • 区分:运行时类的Class对象只有一个,而类的对象可以有无数个
  2. toString()方法提供了将对象字符串化的方式。
  3. equals(Object obj) 方法用于判断对象相等,非常重要。
  4. hashCode()方法用于获取哈希值,在集合使用中非常重要。
  5. finalize()方法,仅作了解,没有实际意义。
  6. clone()方法,克隆,一种创建对象的新方式。