• JavaSE知识重构


    JavaSE知识重构

    我亦无他,唯手熟尔。

    参考:
    B站【零基础 快速学Java】韩顺平 零基础30天学会Java


    final关键字

    final可以修饰类、属性、方法和局部变量

    需要使用final的需求:

    1. 类不可以被继承
    2. 父类的某个方法不可以被子类覆盖/继承(override)
    3. 类的某个属性值不可以被修改
    4. 某个局部变量不可以被修改

    final注意细节

    1. final修饰的属性叫做常量,XXX_XXX_XXX来命名
    2. final修饰的属性在定义时,必须赋初值,并且之后不能修改。
      赋值可以在如下位置:
      • 定义时
      • 在构造器中
      • 在代码块中
    3. 如果final修饰的属性是静态的,则初始化的位置只能是:
      • 定义时
      • 在静态代码块,不能在构造器中赋值
    4. final类不能继承,但可以实例化对象
    5. 如果类不是final类,但含有final方法,则该方法不能重写,但可以被继承。
    6. 如果一个类已经是final类了,没必要再将方法修饰成final方法
    7. final不能修饰构造方法(即构造器)
    8. final、static往往搭配使用,效率高,不会导致类加载(底层编译器做了优化处理)
    9. 包装类(Integer, Double, Float, Boolean等都是final),String类也是final类。

    抽象类

    exercise:
    1、abstract final class A{}能编译通过嘛?错误,final不能继承
    2、abstract public static void test2();能编译通过吗?错误,static关键字和方法重写无关。
    3、abstract private void test3();错误,私有的方法不能重写。
    模板设计模式:

    接口

    内部类

    类的五大成员:
    属性、方法、构造器、代码块、内部类

    什么是内部类

    一个类的内部又完整的嵌套了另一个类结构。被嵌套的类称为内部类(inner class),嵌套其他类的类称为外部类(outer class)。
    内部类最大的特点就是可以直接访问私有属性,并且可以体现类与类之间的包含关系。
    定义类在局部位置(方法中/代码块):(1)局部内部类(2)匿名内部类
    定义在成员位置:(1)成员内部类(2)静态内部类
    在这里插入图片描述

    内部类的特点

    1. 内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号。
    2. 内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否为 private 的。
    3. 内部类声明成静态的,就不能随便访问外部类的成员变量,仍然是只能访问外部类的静态成员变量。

    局部内部类的使用

    局部内部类是定义在外部类的局部位置,比如方法中,并且有类名。

    1. 可以直接访问外部类的所有成员,包括私有的。
    2. 不能添加访问修饰符,因为它的地位就是一个局部变量。局部变量是不能使用修饰符的。但是可以使用final修饰,因为局部变量也可以使用final
    3. 作用域:仅仅在定义它的方法或代码块中。
    4. 局部内部类–访问---->外部类成员 【访问方式:直接访问】
    5. 外部类–>访问—>局部内部类成员 【访问方式:创建对象,再访问(注意:必须在作用域内)】
      注意:
      1 局部内部类定义在方法中/代码块中
      2 作用域再方法体或者代码块中
      3 本质仍然是一个类
    6. 外部其他类–不能访问---->局部内部类(因为 局部内部类地位是一个局部变量)
    7. 如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类.this.成员)去访问
    public class LocalInnerClass {
        public static void main(String[] args) {
            Outer01 outer01 = new Outer01();
            outer01.outer_02();
            System.out.println("outer01的hashcode = " + outer01);
        }
    }
    
    class Outer01{  //外部类
        private int n1 = 100;
        private void outer_f1(){
            System.out.println("外部类实例方法");
        }
        public void outer_02(){  //方法
            // 局部内部类是定义在外部类的局部位置上,通常在方法
            // 不能添加访问修饰符,但是可以使用final修饰
            // 作用域:仅仅在定义它的方法或代码块中
            class Inner01{  //局部内部类(本质仍然是一个类)
                private int n1 = 800;
                public void inner_f1(){
                    // 局部内部类可以直接访问外部类的成员
                    // 如果外部类和内部类的成员重名,默认遵循就近原则
                    // 如果想访问外部类的成员 使用 外部类类名.this.成员 去访问
                    // Outer01.this 本质就是外部类的对象
                    System.out.println("n1 = " + n1);
                    System.out.println("外部类的n1 = " + Outer01.this.n1);
                    System.out.println("Outer01.this hashcode = " + Outer01.this);
                }
            }
    
            Inner01 inner01 = new Inner01();
            inner01.inner_f1();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    n1 = 800
    外部类的n1 = 100
    Outer01.this hashcode = chapter10.innerclass.Outer01@1b6d3586
    outer01的hashcode = chapter10.innerclass.Outer01@1b6d3586

    匿名内部类的使用

    1、本质是类
    2、内部类
    3、该类没有名字
    4、同时还是一个对象
    说明:匿名内部类是定义在外部类的局部位置,比如方法中,并且没有类名
    匿名内部类的基本语法

    new 类或接口(参数列表){
    	类体
    }
    
    • 1
    • 2
    • 3
    public class AnonymousInnerClass {
        public static void main(String[] args) {
            Outer02 outer02 = new Outer02();
            outer02.method();
        }
    }
    
    class Outer02{
        //基于接口的匿名内部类
        //1.需求: 想使用IA接口,并创建对象
        //2.传统方式,是写一个类,实现该接口,并创建对象
        //3.老韩需求是 Tiger/Dog 类只是使用一次,后面再不使用
        //4. 可以使用匿名内部类来简化开发
        //5. tiger的编译类型 ? IA
        //6. tiger的运行类型 ? 就是匿名内部类  Outer04$1
            /*
                底层 会分配 类名 Outer04$1
                class Outer04$1 implements IA {
                    @Override
                    public void cry() {
                        System.out.println("老虎叫唤...");
                    }
                }
             */
        //7. jdk底层在创建匿名内部类 Outer04$1,马上就创建了 Outer04$1实例,并且把地址
        //   返回给 tiger
        //8. 匿名内部类使用一次,就不能再使用
        public void method(){
            IA tiger = new IA(){
    
                @Override
                public void fun() {
                    System.out.println("老虎叫唤...");
                }
            };
            System.out.println("tiger的运行类型 = " + tiger.getClass());
        }
    
    }
    
    interface IA{
        void fun();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    tiger的运行类型 = class chapter10.innerclass.Outer02$1

    匿名内部类可以访问外部类的所有成员,包含私有的。
    不能添加访问修饰符,因为他的地位就是一个局部变量
    作用域:仅仅在定义它的方法或者代码块中
    外部其他类不能访问匿名内部类(因为匿名内部类地位是一个局部变量)
    如果外部类和匿名内部类的成员重名时,匿名内部类访问的话,默认遵循就近原则,如果访问外部类的成员,则可以使用(外部类名.this.成员)去访问。

    //基于类的匿名内部类
     //分析
     //1. father编译类型 Father
     //2. father运行类型 Outer04$2
     //3. 底层会创建匿名内部类
     /*
         class Outer04$2 extends Father{
             @Override
             public void test() {
                 System.out.println("匿名内部类重写了test方法");
             }
         }
      */
     //4. 同时也直接返回了 匿名内部类 Outer04$2的对象
     //5. 注意("jack") 参数列表会传递给 构造器
     Father father = new Father("tom"){
         @Override
         public void test() {
             System.out.println("匿名内部类重写test方法");
         }
     };
     System.out.println("father 对象的运行类型= " + father.getClass());
    //        father.test();
    
     //基于抽象类的匿名内部类
     Animal animal = new Animal() {
    
         @Override
         void eat() {
             System.out.println("小狗吃骨头...");
         }
     };
     System.out.println("animal对象的运行类型=" + animal.getClass());
     animal.eat();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    接收到的name=tom
    father 对象的运行类型= class chapter10.innerclass.Outer02$2
    animal对象的运行类型=class chapter10.innerclass.Outer02$3
    小狗吃骨头…

    public class AnonymousInnerClassDetail {
        public static void main(String[] args) {
            Outer03 outer03 = new Outer03();
            outer03.f1();
            //外部其他类---不能访问----->匿名内部类
            System.out.println("main outer03 hashcode=" + outer03);
        }
    }
    
    class Outer03{
        private int n1 = 99;
        public void f1() {
            //创建一个基于类的匿名内部类
            //不能添加访问修饰符,因为它的地位就是一个局部变量
            //作用域 : 仅仅在定义它的方法或代码块中
            Person p = new Person(){
                private int n1 = 88;
                @Override
                public void hi() {
                    //可以直接访问外部类的所有成员,包含私有的
                    //如果外部类和匿名内部类的成员重名时,匿名内部类访问的话,
                    //默认遵循就近原则,如果想访问外部类的成员,则可以使用 (外部类名.this.成员)去访问
                    System.out.println("匿名内部类重写了 hi方法 n1=" + n1 +
                            " 外部内的n1=" + Outer03.this.n1 );
                    //Outer05.this 就是调用 f1的 对象
                    System.out.println("Outer03.this hashcode=" + Outer03.this);
                }
            };
            p.hi();//动态绑定, 运行类型是 Outer03$1
    
            //也可以直接调用, 匿名内部类本身也是返回对象
            // class 匿名内部类 extends Person {}
            new Person(){
                @Override
                public void hi() {
                    System.out.println("匿名内部类重写了 hi方法,哈哈...");
                }
                @Override
                public void ok(String str) {
                    super.ok(str);
                }
            }.ok("jack");
        }
    }
    
    class Person {//类
        public void hi() {
            System.out.println("Person hi()");
        }
        public void ok(String str) {
            System.out.println("Person ok() " + str);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    匿名内部类重写了 hi方法 n1=88 外部内的n1=99
    Outer03.this hashcode=chapter10.innerclass.Outer03@1b6d3586
    Person ok() jack
    main outer03 hashcode=chapter10.innerclass.Outer03@1b6d3586

    public class InnerClassExercise02 {
        public static void main(String[] args) {
            /*
            1.有一个铃声接口Bell,里面有个ring方法。(右图)
            2.有一个手机类Cellphone,具有闹钟功能alarmClock,参数是Bell类型(右图)
            3.测试手机类的闹钟功能,通过匿名内部类(对象)作为参数,打印:懒猪起床了
            4.再传入另一个匿名内部类(对象),打印:小伙伴上课了
             */
            CellPhone cellPhone = new CellPhone();
            //老韩解读
            //1. 传递的是实现了 Bell接口的匿名内部类 InnerClassExercise02$1
            //2. 重写了 ring
            //3. Bell bell = new Bell() {
            //            @Override
            //            public void ring() {
            //                System.out.println("懒猪起床了");
            //            }
            //        }
            cellPhone.alarmClock(new Bell() {
                @Override
                public void ring() {
                    System.out.println("懒猪起床了");
                }
            });
    
            cellPhone.alarmClock(new Bell() {
                @Override
                public void ring() {
                    System.out.println("小伙伴上课了");
                }
            });
        }
    }
    interface Bell{ //接口
        void ring();//方法
    }
    class CellPhone{//类
        public void alarmClock(Bell bell){//形参是Bell接口类型
            System.out.println(bell.getClass());
            bell.ring();//动态绑定
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    成员内部类使用

    成员内部类是定义在外部类的成员位置,并且没有static修饰。
    1、可以直接访问外部类的所有成员,包括私有的。
    2、可以添加任意访问修饰符(public、protected、默认、private),因为它的地位就是一个成员。
    3、作用域:和外部类的其他成员一样,为整个类。
    4、成员内部类–访问---->外部类成员(属性)【访问方式:直接访问】
    5、外部类–访问---->成员内部类【访问方式:创建对象,再访问】
    6、外部其他类–访问---->成员内部类
    7、如果外部类和内部类的成员重名时,内部类访问的话,默认遵循就近原则,如果访问外部类的成员,则可以使用(外部类.this.成员)去访问

    静态内部类的使用

    静态内部类是定义在外部类的成员位置,并且有static修饰
    1、可以直接访问外部类的所有静态成员,包括私有的,但不能直接访问非静态成员。
    2、可以添加任意访问修饰符(public、protected、默认、private),因为他的地位就是一个成员
    3、作用域:同其他成员,为整个类
    4、静态内部类–访问---->外部类(比如:静态属性)【访问方式:直接访问所有静态成员】
    5、外部类–>访问---->静态内部类【访问方式:创建对象,再访问】
    6、外部其他类–>访问---->静态内部类
    7、如果外部类和静态内部类的成员重名时,静态内部类访问时,默认遵循就近原则,如果访问外部类的成员,则可以使用(外部类名.成员)去访问

    public class StaticInnerClass01 {
        public static void main(String[] args) {
            Outer05 outer05 = new Outer05();
            outer05.m1();
    
            // 外部其它类 使用静态内部类
            // 方式一
            Outer05.Inner05 inner05 = new Outer05.Inner05();
            inner05.say();
    
            // 方式2
            // 编写一个方法,可以返回静态内部类的对象实例
            Outer05.Inner05 inner051 = outer05.getInner05();
            inner05.say();
            Outer05.Inner05 inner05_ = Outer05.getInner05_();
            inner05.say();
        }
    }
    
    
    class Outer05{
        private int n1 = 10;
        private static String name = "张三";
        private static void cry(){};
    
        //Inner05就是静态内部类
        //1. 放在外部类的成员位置
        //2. 使用static 修饰
        //3. 可以直接访问外部类的所有静态成员,包含私有的,但不能直接访问非静态成员
        //4. 可以添加任意访问修饰符(public、protected 、默认、private),因为它的地位就是一个成员
        //5. 作用域 :同其他的成员,为整个类体
        static class Inner05{
            private static String name = "我亦无他,唯手熟尔。";
            // 如果外部类和静态内部类的成员重名时,静态内部类访问的时候
            // 默认遵循就近原则,如果访问外部类的成员,则可以使用(外部类名.成员)
            public void say(){
                System.out.println(name + " 外部类name = " + Outer05.name);
                // 静态内部类直接使用外部类的静态方法
                cry();
            }
        }
    
        //外部类---访问------>静态内部类 访问方式:创建对象,再访问
        public void m1(){
            Inner05 inner05 = new Inner05();
            inner05.say();
        }
    
        public Inner05 getInner05(){
            return new Inner05();
        }
    
        public static Inner05 getInner05_(){
            return new Inner05();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    枚举和注解

    枚举

    1、使用enum关键字实现枚举类,默认继承Enum类,而且是一个final类
    2、如果使用无参构造器创建枚举对象,则实参列表和小括号可以省略
    3、当有多个枚举对象时,使用逗号间隔,最后有一个分号结尾。
    4、枚举对象必须放在枚举类的行首

    public class Enumeration03 {
        public static void main(String[] args) {
            System.out.println(Season2.AUTUMN);
            System.out.println(Season2.SUMMER);
        }
    }
    //演示使用enum关键字来实现枚举类
    enum  Season2 {//类
        //定义了四个对象, 固定.
    //    public static final Season SPRING = new Season("春天", "温暖");
    //    public static final Season WINTER = new Season("冬天", "寒冷");
    //    public static final Season AUTUMN = new Season("秋天", "凉爽");
    //    public static final Season SUMMER = new Season("夏天", "炎热");
        //如果使用了enum 来实现枚举类
        //1. 使用关键字 enum 替代 class
        //2. public static final Season SPRING = new Season("春天", "温暖") 直接使用
        //   SPRING("春天", "温暖") 解读 常量名(实参列表)
        //3. 如果有多个常量(对象), 使用 ,号间隔即可
        //4. 如果使用enum 来实现枚举,要求将定义常量对象,写在前面
        //5. 如果我们使用的是无参构造器,创建常量对象,则可以省略 ()
        SPRING("春天", "温暖"), WINTER("冬天", "寒冷"), AUTUMN("秋天", "凉爽"),
        SUMMER("夏天", "炎热")/*, What()*/;
    
        private String name;
        private String desc;//描述
    
        private Season2() {//无参构造器
    
        }
    
        private Season2(String name, String desc) {
            this.name = name;
            this.desc = desc;
        }
    
        public String getName() {
            return name;
        }
    
        public String getDesc() {
            return desc;
        }
    
        @Override
        public String toString() {
            return "Season{" +
                    "name='" + name + '\'' +
                    ", desc='" + desc + '\'' +
                    '}';
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    在这里插入图片描述

    enum常用方法
    1. toString:Enum 类已经重写过了,返回的是当前对象名,子类可以重写该方法,用于返回对象的属性信息
    2. name:返回当前对象名(常量名),子类中不能重写
    3. ordinal:返回当前对象的位置号,默认从0 开始
    4. values:返回当前枚举类中所有的常量
    5. valueOf:将字符串转换成枚举对象,要求字符串必须为已有的常量名,否则报异常!
    6. compareTo:比较两个枚举常量,比较的就是编号!
    7. 使用enum 关键字后,就不能再继承其它类了,因为enum 会隐式继承Enum,而Java 是单继承机制。
    8. 枚举类和普通类一样,可以实现接口

    注解

    异常

    常用类

    String类

    在这里插入图片描述
    在这里插入图片描述

    hsp and hava

  • 相关阅读:
    机器学习之支持向量机(SVM)的求解方法
    「梦华录X喜茶」这波现象级联名营销 让小程序爆单了!
    高质量英文文献应该如何查找并且阅读?
    98.验证二叉搜索树
    机器学习之过拟合与欠拟合,K折交叉验证详解【含代码】
    RK3568驱动指南|第五期-中断-
    80%的前端开发都答不上来的js异步面试题
    鸿蒙应用开发-初见:ArkUI
    java服务器调试指南
    我开源了一个加密算法仓库,支持18种算法!登录注册业务可用!
  • 原文地址:https://blog.csdn.net/qq_43629083/article/details/128178196