Java 一个类中能够嵌套另一个类,语法格式以下:html
class OuterClass { // 外部类 // ... class NestedClass { // 嵌套类,或称为内部类 // ... } }
嵌套类有以下几种类型:java
最简单的一种内部类,形式以下,跟其余变量同样,是一个类中的一个成员jvm
class Outer { String str = "hello"; public Outer(String str) { this.str = str; } /* 内部类 */ class Inner { public void showStr() { System.out.println(str); } } }
编译器会在编译时生成外部类和内部类两个字节码文件,还会给内部类的无参构造函数增长一个参数,为外部类的一个应用,且指向了外部类,故能够随意使用外部类一切。函数
侧面说明成员内部类依赖于外部类的优先建立,否则会初始化失败this
定义在一个方法或者一个做用域里面的类,局部内部类的访问仅限于方法内或者该做用域内spa
class MyClass{ public MyClass() { } } class Outer{ public Outer(){ } public MyClass getInner{ /* 局部内部类 */ class Inner extends MyClass{ int age = 0; } return new Inner(); } }
局部内部类就像是方法里面的一个局部变量同样,是不能有 public、protected、private 以及 static 修饰符的线程
先看一下官方给的例子code
public class HelloWorldAnonymousClasses { /** * 包含两个方法的HelloWorld接口 */ interface HelloWorld { public void greet(); public void greetSomeone(String someone); } public void sayHello() { // 一、局部类EnglishGreeting实现了HelloWorld接口 class EnglishGreeting implements HelloWorld { String name = "world"; public void greet() { greetSomeone("world"); } public void greetSomeone(String someone) { name = someone; System.out.println("Hello " + name); } } HelloWorld englishGreeting = new EnglishGreeting(); // 二、匿名类实现HelloWorld接口 HelloWorld frenchGreeting = new HelloWorld() { String name = "tout le monde"; public void greet() { greetSomeone("tout le monde"); } public void greetSomeone(String someone) { name = someone; System.out.println("Salut " + name); } }; // 三、匿名类实现HelloWorld接口 HelloWorld spanishGreeting = new HelloWorld() { String name = "mundo"; public void greet() { greetSomeone("mundo"); } public void greetSomeone(String someone) { name = someone; System.out.println("Hola, " + name); } }; englishGreeting.greet(); frenchGreeting.greetSomeone("Fred"); spanishGreeting.greet(); } public static void main(String... args) { HelloWorldAnonymousClasses myApp = new HelloWorldAnonymousClasses(); myApp.sayHello(); } }
匿名类表达式包含如下内部分:htm
本部分参考JAVA匿名内部类(Anonymous Classes)对象
静态内部类是不须要依赖于外部类的,而且它不能使用外部类的非static成员变量或者方法,这个和普通静态方法不能访问非静态方法或变量的原理同样,具体能够了解一下类的加载生命周期。
简单地说就是静态变量或方法是属于类的,非静态方法或变量是属于对象的,jvm加载类的时候就为类的静态变量或方法分配内存的,而非静态的须要等到要初始化对象时候才给分配内存,而这个过程是动态的,也就是等到咱们何时想用,才会有累的初始化过程。
简单举个例子:
class Outer { int a = 1 static int a = 2; public Outter() { } /* 静态内部类 */ static class Inner { public Inner() { System.out.println(a); // 编译会报错 System.out.println(b); } } }
使用:
public class Test { public static void main(String[] args) { Outer.Inner inner = new Outer.Inner(); } }
为何在 Java 中须要内部类?总结一下主要有如下四点内部类的使用场景和好处: