Java内部类了解一下

配图

前言

Java有四种内部类:成员内部类,局部内部类,静态内部类和匿名内部类。这篇文章主要分别说一下这四种内部类的特点。

内部类

《Think in java》 中提到过,使用内部类最吸引人的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。

ps:利用匿名内部类,可以实现Java多继承;另一种是接口的多实现。

内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两类。对于一个名为OuterClass的外部类和其内部定义的InnerClass内部类。编译完成后出现OuterClass.classOuterClass$InnerClass.class两个类文件。

关于内部类的new和this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class OuterClass {
private String name;

private class InnerClass {
private InnerClass(String name) {
// OuterClass.this 获取外部类的引用
OuterClass.this.name = name;
}

private void print() {
System.out.println("name:" + name);
}
}

public static void main(String[] args) {
OuterClass outerClass = new OuterClass();
// outerClass.new 创建内部类对象
OuterClass.InnerClass innerClass = outerClass.new InnerClass("yoga");
innerClass.print();
}
}

上面这段代码的注释已经很清楚了,我们可以通过OuterClass.this获取外部类的引用,外部类对象通过.new来创建内部类。

成员内部类

成员内部类是外部类的一个成员,与外部类的属性和方法的等级是一样的。它可以任意的访问外部类的属性和方法(包括private修饰的);而外部类需要通过内部类实例来访问内部类的属性和方法。

特点

  1. 成员内部类不能包含任何static修饰的变量和方法。
  2. 成员内部类依附于外部类,所以需要先创建外部类再创建内部类。

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class MemberOuterClass {
private String name;

private class MemberInnerClass {
private MemberInnerClass(String name) {
MemberOuterClass.this.name = name;
}

private void print() {
System.out.println("name:" + name);
}
}

public static void main(String[] args) {
MemberOuterClass memberOuterClass = new MemberOuterClass();
MemberOuterClass.MemberInnerClass memberInnerClass = memberOuterClass.new MemberInnerClass("yoga");
memberInnerClass.print();
}
}

局部内部类

局部内部类定义在方法中的内部类,与局部变量有点类似。局部内部类前面不加privatepublic修饰符。

特点

  1. 作用域为定义该局部内部类的代码块。
  2. 局部内部类不可以定义静态变量。
  3. 如果在静态方法中:可以访问外部类中所有静态成员,包含私有;如果在实例方法中:可以访问外部类中所有的成员,包含私有。
  4. 局部内部类可以访问所在方法中定义的局部变量,但是要求局部变量必须使用final修饰 。

代码示例

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
public class LocalOuterClass {
private String name = "yoga";
private static int age = 2;

private void test1() {
final String sex = "male";
class LocalInner {
private void print() {
System.out.println("name : " + name);
System.out.println("age : " + age);
System.out.println("sex : " + sex);
}
}
new LocalInner().print();
}

static private void test2() {
final String address = "HangZhou";
class LocalInner {
private void print() {
// System.out.println("name : " + name); 无法访问private属性
System.out.println("age : " + age);
System.out.println("address : " + address);
}
}
new LocalInner().print();
}

public static void main(String[] args) {
LocalOuterClass.test2();
new LocalOuterClass().test1();
}
}

匿名内部类

匿名内部类是没有名字的局部内部类。没有修饰符。

特点

  1. 没有构造器。

代码示例

1
2
3
4
5
6
7
8
9
10
public class OuterClass {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("匿名内部类");
}
}).start();
}
}

静态内部类

静态内部类是声明在外部类内,方法体外,并且使用static修饰的内部类 。

特点

  1. 它的创建是不需要依赖于外围类的:
    • 在外部类的外部构建内部类的实例:new Outer.Inner();
    • 在外部类的内部构建内部类的实例:new Inner();
  2. 它不能使用任何外围类的非static成员变量和方法。

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class StaticOuterClass {
private static String name = "yoga";
private int age;

/**
* 静态内部类
*/
static class StaticInnerClass {
/**
* 定义在静态内部类中的静态属性
*/
public static String sex = "male";

public static void print() {
System.out.println("name:" + name);
}
}

public static void main(String[] args) {
StaticOuterClass staticOuterClass = new StaticOuterClass();
StaticInnerClass.print();
}
}

欢迎关注博主其他的文章。

感谢您的支持!

本文标题:Java内部类了解一下

文章作者:yoga

发布时间:2017年01月21日 - 21:01

原始链接:https://yoga0521.github.io/2017/01/21/Java内部类了解一下/

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。 转载请注明出处!