《JAVASE系列》类和对象篇:代码块与内部类

《JAVASE系列》类和对象篇:代码块与内部类

文章目录

  • 《JAVASE系列》类和对象篇:代码块与内部类
    • 前言:
    • 1.代码块
      • 1.1 实例代码块
      • 1.2 静态代码块
    • 2.内部类
      • 2.1 内部类的分类
      • 2.2 如何实例化 实例内部类 对象
      • 2.3 实例内部类知识点:
      • 2.4 静态内部类知识点:
      • 2.5 了解局部代码块
    • 总结:

前言:

本章主要学习:

1.实例代码块与静态代码块

2.封装之内部类

参考书籍:《java核心卷1》

你若盛开,清风自来。

1.代码块

代码块有多种:

  1. 普通代码块
  2. 实例代码块
  3. 静态代码块
  4. 同步代码块

本节只介绍实例代码块与静态代码块

1.1 实例代码块

实例代码块:定义在类中的代码块(不加修饰符)

例如:

class  A {
    public A(){
        System.out.println("A的构造方法");
    }
    {
        System.out.println("A的实例代码块");
    }
}
public class test{
    public static void main(String[] args) {
        A a = new A();
    }
}

由上面的代码运行结果:

《JAVASE系列》类和对象篇:代码块与内部类_第1张图片

可以得出结论:

实例代码块的优先级高于构造方法,再构造方法执行前先执行实例代码块。

从字节码的角度来说:是把实例代码块的内容拷贝到了构造方法之前。所以实例代码块会优先执行于构造方法。

实例代码块一般用于初始化成员变量。

class  A {
    private int a;
    private int b;
    private int c;
    {
        this.a = 10;
        this.b = 20;
        this.c = 30;
    }
}

1.2 静态代码块

使用static定义的代码块称为静态代码块。一般用于初始化静态成员变量。

静态代码块不能初始化非静态成员。
《JAVASE系列》类和对象篇:代码块与内部类_第2张图片

优先级问题:

class  A {
    private static int a1;
    private static int b1;
    private static int c1;

    private int a;
    private int b;
    private int c;
    public A(){
        System.out.println("构造方法");
    }

    {
        this.a = 10;
        this.b = 20;
        this.c = 30;
        System.out.println("实例代码块");
    }
    static {

        a1 = 10;
        b1 = 20;
        c1 = 30;
        System.out.println("静态代码块");
    }
}
public class test{
    public static void main(String[] args) {
        A a = new A();
        System.out.println("=============");
        A b = new A();
    }
}

运行结果:

《JAVASE系列》类和对象篇:代码块与内部类_第3张图片

我们可以得出结论:

  • 静态代码块的优先级最高,其次是实例代码块,最后才是构造方法。
  • 当多个对线执行时,静态代码块只执行一次。
  • 如果有多个静态代码块,则根据定义的顺序来执行

2.内部类

在 Java 中,可以将一个类定义在另一个类或者一个方法的内部,
前者称为内部类,后者称为外部类。

内部类也是封装的一种体现。

public class Outclass {
    class Innerclass{
 
   }
}
// OutClass是外部类
// InnerClass是内部类

2.1 内部类的分类

public class OutClass {
    // 成员位置定义:未被static修饰 ---> 普通内部类
    public class InnerClass1{
   }
 
    // 成员位置定义:被static修饰 ---> 静态内部类
    static class InnerClass2{
 
   }
    public void method(){
        // 方法中也可以定义内部类 ---> 局部内部类
        class InnerClass5{
        }
    }
}

根据内部类定义的位置不同,一般可以分为以下几种形式:

  1. 普通内部类
  2. 静态内部类
  3. 局部内部类(较少用到)
  4. 匿名内部类(与多线程有关)

本章主要讲解普通内部类和静态内部类。

2.2 如何实例化 实例内部类 对象

两种方式:

第一种:先创建外部类再创建内部类 (比较容易理解)

class Outclass{
    private int a;
    private int b;
    private int c;
    class Innerclass{
        public Innerclass(){
            System.out.println("普通内部类");
        }
    }
}
public class test{
    public static void main(String[] args) {
        Outclass outclass = new Outclass();                          
        //先创建外部类
        Outclass.Innerclass innerclass= outclass.new Innerclass();
        //再创建内部类
//      外部类名.内部类名 对象名 = 外部类对象.new 内部类名();
    }
}

第二种:直接创建

public class test{
    public static void main(String[] args) {
        OutClass.InnerClass innerClass1 = new OutClass().new InnerClass();
     //外部类名.内部类名 对象名 = new 外部类类名().new 内部类名();
    }
}

2.3 实例内部类知识点:

  1. 实例内部类中定义静态成员变量的注意点

    《JAVASE系列》类和对象篇:代码块与内部类_第4张图片

    《JAVASE系列》类和对象篇:代码块与内部类_第5张图片

    所以实例代码块中是不能定义静态变量的,如果要定义,必须将该静态变量用final修饰。

    《JAVASE系列》类和对象篇:代码块与内部类_第6张图片

  2. 实例内部类中,成员变量与外部类成员变量重名时。

    class Outclass{
        private int a;
        private int b;
        private int c;
        public Outclass(){
            this.a = 100;
        }
    
        class Innerclass{
            private int a;
            public Innerclass(){
                this.a = 10;//这里的this是内部类对象的引用
            }
            public void print(){
                System.out.println(this.a);
                System.out.println(Outclass.this.a);
                //Outclass.this  在内部类中调用外部类对象的引用
            }
            public static final int data = 60;
        }
    }
    

    运行结果:

    《JAVASE系列》类和对象篇:代码块与内部类_第7张图片

    结论:

    • 优先使用自己的成员变量。

    • 可以通过 外部类名.this 访问外部类的成员变量

      实例内部类不仅包含了当前对象的this也包含了外部类的this。

  3. 实例内部类不能包含静态方法

    《JAVASE系列》类和对象篇:代码块与内部类_第8张图片

  4. 外部类中不能直接访问实例内部类的成员,如果要访问需要先创建内部类的对象

2.4 静态内部类知识点:

class Outclass{
    static class Innerclass{
    }
}
  1. 如何实例化静态内部类对象:

    由于实例化静态内部类不依赖于外部类对象,所以:

    public class test{
        public static void main(String[] args) {
            Outclass.Innerclass innerclass = new Outclass.Innerclass();
        }
    }
    
  2. 在静态内部类中,只能访问外部类的静态成员,如果要访问普通成员变量,则需要实例化外部类对象。

    直接实例化外部类对象

    class Outclass{
        private static int m;
        private static int n;
        private int a;
        private int b;
        private int c;
        public Outclass(){
            this.a = 100;
        }
        static class Innerclass1{
            private int d1;
            private int d2;
            private int d3;
            Outclass outclass = new Outclass(); //实例化对象
            public void func(){
                m = 10;
                outclass.a = 10;
                System.out.println("静态内部类");
            }
        }
    }
    

    传入实例化外部类对象

    class Outclass{
        private static int m;
        private static int n;
        private int a;
        private int b;
        private int c;
        public Outclass(){
            this.a = 100;
        }
        static class Innerclass1{
            private int d1;
            private int d2;
            private int d3;
            Outclass outclass = new Outclass();  //null空对象用来接收
            public Innerclass1(Outclass out){ //构造方法接收对象
                outclass = out;
            }
            public void func(){
                m = 10;
                outclass.a = 10;
                System.out.println("静态内部类");
            }
        }
    }
    public class test{
        public static void main(String[] args) {
            Outclass outclass = new Outclass();
            Outclass.Innerclass1 innerclass = new Outclass.Innerclass1(outclass);
            innerclass.func();
        }
    }
    

静态内部类与静态变量/方法都是外部类的特征,不依赖于对象,所以静态内部类可以访问静态的外部类属性,而静态内部类访问外部类的普通成员/方法。则需要实例化外部类对象

个人理解(如有错误请指正!)

2.5 了解局部代码块

定义在外部类的方法体或者{}中,该种内部类只能在其定义的位置使用,一般使用的非常少,此处简单了解下语法格式。

public class OutClass {
    int a = 10;
    public void method(){
        int b = 10;
 
        // 局部内部类:定义在方法体内部
        // 不能被public、static等访问限定符修饰
        class InnerClass{
            public void methodInnerClass(){
                System.out.println(a);
                System.out.println(b);
           }
       }
 
        // 只能在该方法体内部使用,其他位置都不能用
        InnerClass innerClass = new InnerClass();
        innerClass.methodInnerClass();
   }
    public static void main(String[] args) {
        
  }
}

注意:

  1. 局部内部类只能在所定义的方法体内部使用
  2. 不能被public、static等修饰符修饰
  3. 几乎不会使用

总结:

学习完需要能回答出以下问题:

  1. 代码块以及构造方法的优先级
  2. 静态代码块可以初始化非静态成员吗?为什么?
  3. 示例内部类中可以有静态方法吗?
  4. 实例内部类中如何访问外部类的普通成员?
  5. 静态内部类中如何访问外部类的普通成员?

感谢阅读!

与君共勉!

你可能感兴趣的:(《JAVASE》系列,java,后端,算法)