5.Java_代码块普通代码块、构造块、静态代码块、同步代码块以及内部类的使用和创建、内部类与外部类的关系、语法、优缺点分类(成员内部类、静态内部类、方法内部类、匿名内部类)

一、代码块:根据代码块出现的位置以及关键字,分为以下四种

1.普通代码块(了解):定义在方法中的代码块。

2.构造块(*****):定义在类中的代码块(不加任何修饰符)

  • 在对象产生时,优先于构造方法执行。
  • 有几个对象产生,就调用几次构造块。
  • 用于在构造方法执行前完成一些属性的初始化。

3.静态代码块:

(1)非主类的静态代码块:

  • 在类加载时执行(什么时候用到这个类,就叫类加载)。
  • 优先于构造块执行。
  • 无论有几个对象,只调用一次。

(2)主类中的静态代码块:

  • 优先于主方法执行。

4.同步代码块(多线程同步部分再议)

小结:

  • 非主类:静态代码块 > 构造块 > 构造方法
  • 主类:静态代码块 > 主方法执行

 

二、内部类:在类内部进行其他类型结构嵌套操作

1.内部类的优点:

(1)内部类与外部类可以方便的访问彼此的私有域(包括私有方法、私有属性)

(2)内部类是另外一种封装(保护性),对外部其他类隐藏。(心脏包在人身体内部)

(3)内部类可以实现java单继承的局限。

2.内部类的缺点:结构复杂

3.内部类与外部类的关系:

(1)对于非静态内部类,内部类 的创建需要依赖外部类对象,在没有外部类实例之前无法创建非静态内部类。

(2)内部类是一个相对独立的个体,与外部类没有is-a关系。

(3)内部类可以直接访问外部类的元素(包含私有域),但是外部类不可以直接访问内部类元素,需要通过内部类的引用间接访问。

4.创建内部类的语法(在外部类外部):

(1)创建非静态内部类

外部类.内部类   内部类引用  =  new  外部类().new  外部类();

Outter.Inner   in = new  Outter().new  Inner();

(2)创建静态内部类

外部类.内部类   内部类引用  =  new  外部类.内部类();

Outter.Inner  in  =  new  Outter.Inner();

5.内部类的分类:

(1)成员内部类(成员方法)

          ①成员内部类不能存在任何static变量或方法,但是可以访问外部类的静态域。

          ②成员内部类依附外部类,所以只有先创建了外部类才能创建内部类。

(2)静态内部类(静态方法)

          ①静态内部类的创建不需要依赖外部类,可以直接创建。

          ②静态内部类不可以使用任何外部类的非static域(包含属性与方法),但是可以存在自己的成员变量。

(3)方法内部类

          ①方法内部类不允许使用访问权限修饰符。public、private、protected均不允许。

class Outter{
    private int num=5;
    public void display(final int temp){//此处final可隐藏,用public修饰方法,则会报错:非法表达式的开始
        //方法内部类
        public class Inner{
            
        }
    }
}
public class Test{
    public static void main(String[] args){
        new Outter();
    }
}

           ②方法内部类对外部完全隐藏,除了创建这个类的方法可以访问它以外,其它的地方均不能访问。

           ③方法内部类如果想使用方法形参,该形参必须使用final声明(JDK将形参变为隐式final声明)。

class Outter{
    private int num = 5;
    public void display(final int temp){//此处final可省略
        //方法内部类
        class Inner{
            public void fun(){
                System.out.println(num);
                temp++;    //temp如果进行运算引用,则报错:从内部类引用的本地变量必须是最终变量或实际上的最终变量
                System.out.println(temp);
            }
        }
        new Inner().fun();
    }
}
public class Test{
    public static void main(String[] args){
        Outter out = new Outter();
        out.display(20);
    }
}

            ④匿名内部类(lamdba表达式前身):是一个没有名字的方法内部类,因此特点与方法内部类完全一样。

除此之外:还有两个自己的特点:

  • 匿名内部类必须继承一个抽象类或实现一个接口。
  • 匿名内部类没有构造方法,因为它没有类名。
    //interface实现接口
    interface MyInterface{
        void Test();
    }
    class Outter{
        private int num = 5;
        public void display(int temp){
            //匿名内部类,匿名的实现了MyInterface接口
            new MyInterface(){
                @override
                public void test(){
                    System.out.println("匿名实现MyInterface接口");
                    System.out.println(temp);
                }
            }.test();
        }
    }
    public class Test2{
        public static void main(String[] args){
            Outter out = new Outter();
            out.display(20);
        }
    }
    public class Test3{
        public static void main(String[] args){
            //新启了一个线程
            //new Thread(()->System.out.println("hello bit")).start();与以下语句是一样的性质。
            new Thread(new Runnable(){
                @override
                public void run(){
                    System.out.println("hello bat");
                }
            }).start();
         }
    }

    总结:如果类名称上出现了".",应当立即想到内部类的概念。

 

 

 

 

 

 

 

 

 

 

 

 

猜你喜欢

转载自blog.csdn.net/qq_40408483/article/details/83540140