Java内部类(成员内部类、静态内部类、局部内部类、局部内部类)

简介: Java内部类(成员内部类、静态内部类、局部内部类、局部内部类)

前言: 什么是内部类?

类的五大成员:

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

在一个类里面,再定义一个类就是内部类。

  • 内部类表示的事物是外部类的一部分
  • 内部类单独出现没有任何意义
  • 内部类的访问特点:
  • 内部类可以直接访问外部类的成员,包括私有
  • 外部类要访问内部类的成员,必须创建对象
public class Car {
    private String carName;
    private int carAge;
    private String carColor;
    public void show() {
        System.out.println(carName);
        System.out.println(engineName); // 报错
        //创建内部类对象
        Engine engine = new Engine();
        System.out.println(engine.engineName);
    }
    class Engine {
        String engineName;
        int engineAge;
        public void show() {
            System.out.println(engineName);
            System.out.println(carName);
        }
    }
}

一、成员内部类

1.1 成员内部类的代码如何书写

  • 写在成员位置的,属于外部类的成员。
  • 成员内部类可以被一些修饰符所修饰,比如:private,默认,protected,public,static等
  • 在成员内部类里面,JDK16之前不能定义静态变量,JDK16开始才可以定义静态变量。
public class Car {
    private String carName;
    private int carAge;
    private String carColor;
    public void show() {
      System.out.println("外部类方法");
    }
    private class Engine {  //成员内部类,可添加修饰符
        String engineName;
        int engineAge;
        public void show() {
            System.out.println("内部类方法");
        }
    }
}

1.2 如何创建成员内部类的对象

  • 方式一:
  • 在外部类中编写方法,对外提供内部类的对象。
public class Outer {
    String name;
    class Inner {
    }
    public Inner getInstance() {
        return new Inner();
    }
}
public class Test {
    public static void main(String[] args) {
        System.out.println(new Outer().getInstance());
    }
}
  • 方式二:
  • 直接创建格式:外部类名.内部类名对象名=外部类对象.内部类对象;
public class Outer {
    String name;
    class Inner {
        
    }
}
public class Test {
    public static void main(String[] args) {
        Outer.Inner oi = new Outer().new Inner();
    }
}

1.3 成员内部类如何获取外部类的成员变量

public class Outer {
    private int a = 10;
    
    class Inner {
        private int a = 20;
        public void show() {
            int a = 30;
            System.out.println(a); // 30
            System.out.println(this.a); // 20
            System.out.println(Outer.this.a); // 10
        }
    }
}
public class Test {
    public static void main(String[] args) {
        //创建内部类对象,并调用show方法
        Outer.Inner oi = new Outer().new Inner();
        oi.show();
    }
}

代码分析:

在执行代码时,首先调用main方法,此时在栈内存中添加main方法,并记录Outer.Inner oi的地址,

方法区中有Test.class的字节码文件,以及其中的main方法、Outer.class和Inner.class的字节码文件以及他们各自的所有成员变量和成员方法

堆内存中分别记录了外部类对象和内部类对象

注意:在内部类对象中还隐含了外部类对象的地址。


二、静态内部类

  • 静态内部类也是成员内部类中的一种
  • 静态内部类只能访问外部类中的静态变量和静态方法,如果想要访问非静态的需要创建对象
  • 创建静态内部类对象的格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();
  • 调用非静态方法的格式:先创建对象,用对象调用
  • 调用静态方法的格式:外部类名内部类名.方法名();
public class Outer {
    int a = 10;
    static int b = 20;
    static class Inner {
        public void method1 () {
            //报错
            //System.out.println(a);
        }
        public void method2() {
            System.out.println(b);
        }
    }
}
public class Outer {
    int a = 10;
    static int b = 20;
    static class Inner {
        public void method1 () {
            System.out.println("非静态方法被调用了");
        }
        public static void method2() {
            System.out.println("静态方法被调用了");
            System.out.println(b);
        }
    }
}
public class Test {
    public static void main(String[] args) {
        Outer.Inner oi = new Outer.Inner();
        oi.method1();
        Outer.Inner.method2();
    }
}

三、局部内部类

  • 1.将内部类定义在方法里面就叫做局部内部类,类似于方法里面的局部变量。
  • 2.外界是无法直接使用,需要在方法内部创建对象并使用。
  • 3.该类可以直接访问外部类的成员,也可以访问方法内的局部变量。
public class Outer {
    public void show() {
        final int a = 10;
        //局部内部类
        class Inner {
            String name;
            int age;
            
            public void method1() {
                System.out.println("局部内部类中的method1方法");
            }
            public void method2() {
                System.out.println("局部内部类中的method2方法");
            }
        }
        //创建局部内部类对象
        Inner i = new Inner();
        System.out.println(i.name);
        System.out.println(i.age);
        i.method1();
        i.method2();
    }
}

四、 匿名内部类

  • 1.继承/实现关系
  • 2.方法的重写
  • 3.创建对象

接口

public interface Swim {
    public void swim();
}

抽象类

public abstract class Animal {
    public abstract void cat();
}

匿名内部类创建

public class Test {
    public static void main(String[] args) {
        new Swim() {
            @Override
            public void swim() {
                System.out.println("实现了Swim中的方法");
            }
        };
        new Animal() {
            @Override
            public void cat() {
                System.out.println("继承Animal后实现cat方法");
            }
        };
    }
}


相关文章
|
2月前
|
Java 编译器
【Java】内部类
【Java】内部类
23 0
|
4月前
|
Java
【Java基础面试二】、个Java文件里可以有多个类吗(不含内部类)?
这篇文章讨论了Java文件中类的定义规则,指出一个Java文件可以包含多个类(不包含内部类),但其中最多只能有一个public类,且如果有public类,它的名称必须与文件名一致。
|
4月前
|
算法 Java
12 Java常用类(一)(内部类+object类+包装类)
12 Java常用类(一)(内部类+object类+包装类)
43 5
|
5月前
|
Java
Java进阶之内部类
【7月更文挑战第13天】Java内部类增进代码组织与封装,允许直接访问外部类成员,包括私有成员。主要有四种类型:成员、静态、局部和匿名内部类。匿名内部类常用于一次性实现接口或扩展类。内部类可隐藏实现细节,减少命名冲突,并在特定上下文中定义辅助类。示例展示了静态和非静态内部类如何在Shape类中封装Circle和Rectangle。使用内部类能提升代码可读性,但可能增加复杂性。
47 6
|
4月前
|
Java
【Java】内部类、枚举、泛型
【Java】内部类、枚举、泛型
|
6月前
|
Java
一篇文章讲明白Java中内部类详解—匿名内部类
一篇文章讲明白Java中内部类详解—匿名内部类
102 2
|
6月前
|
设计模式 安全 Java
Java设计模式:代理模式的静态和动态之分(八)
Java设计模式:代理模式的静态和动态之分(八)
|
6月前
|
Java
Java内部类相关内容总结和解读
Java内部类相关内容总结和解读
35 0
|
7天前
|
安全 Java API
java如何请求接口然后终止某个线程
通过本文的介绍,您应该能够理解如何在Java中请求接口并根据返回结果终止某个线程。合理使用标志位或 `interrupt`方法可以确保线程的安全终止,而处理好网络请求中的各种异常情况,可以提高程序的稳定性和可靠性。
37 6
|
22天前
|
设计模式 Java 开发者
Java多线程编程的陷阱与解决方案####
本文深入探讨了Java多线程编程中常见的问题及其解决策略。通过分析竞态条件、死锁、活锁等典型场景,并结合代码示例和实用技巧,帮助开发者有效避免这些陷阱,提升并发程序的稳定性和性能。 ####
下一篇
DataWorks