Java内部类相关内容总结和解读

简介: Java内部类相关内容总结和解读

什么是内部类
什么是内部类?
顾名思义,就是将一个类的定义放在另一个类的内部。
概念很清楚,感觉很简单,其实关键在于这个内部类放置的位置,可以是一个类的作用域范围、一个方法的或是一个代码块的作用域范围。
所以理解了概念只是第一步,掌握细节才能彻底搞定Java的内部类特性。
看例子,这是最普通的内部类:

public class Product1 {
class Design{
private String name = "P30 pro";
public String showName() {
return name;
}
}
class Content{
private int i;
Content(int value){
i = value;
int value() {return i;}
public void show(int value) {
Content c = new Content(value);
Design d = new Design();
System.out.println(d.showName());
System.out.println(c.value());
public static void main(String[] args) {
Product1 p = new Product1();
p.show(6000);
}
说明:
上面这个示例展示了内部类最基础的用法,就是将一个或多个类的定义放在了外围内的内部。可以看到在show()方法中的使用和普通类一样,没有区别。
另外,在外围类的非静态方法之外的任意位置,不能通过直接new 内部类的方式创建内部类对象。会报编译错误。
像这样:
在这里插入图片描述
还有这样:
如果想要在外围类非静态方法之外创建内部类对象。怎么办呢?
正确的姿势是这样子:
在外围类中增加两个公共方法,返回内部类的引用。
public Design design() {
return new Design();
public Content content(int value) {
return new Content(value);
然后通过外部类对象调用方法的方式获取内部类对象。
Product2 p = new Product2();
Product2.Content c1 = p.content(100);
Product2.Design d1 = p.design();
值得注意的是,外部类之外的其他类,也是不能直接访问到该外部类的内部类对象的。
会报编译错误。这也符合内部类的定义,就是为外围类服务的嘛!
内部类的特性
1.可以链接到外部类
当生成一个内部类对象时,此对象与制造它的外围对象之间就有了一种联系,所以它能访问外围对象的所有成员,而不需要任何特殊的条件。
下面的例子是《Java编程思想》中的示例
首先定义一个Selector接口
public interface Selector {
boolean end();
Object current();
void next();
然后定义一个Sequence类,其中定义有一个private的内部类。
public class Sequence {
private Object[] items;
private int next = 0;
public Sequence(int size) {items = new Object[size];}
public void add(Object x) {
if(next < items.length) {
items[next++] = x;
private class SequenceSelector implements Selector{
private int i = 0;
public boolean end() {
return i == items.length;
public Object current() {
return items[i];
public void next() {
if(i < items.length) {i++;}
public Selector selector() {
return new SequenceSelector();
Sequence sequence = new Sequence(10);
for(int i = 0; i < 10; i++) {
sequence.add(Integer.toString(i));
Selector selector = sequence.selector();
while(!selector.end()) {
System.out.print(selector.current() + " ");
//代码效果参考:http://0791zd.com/zx/art_6848.html
selector.next();

可以看到SequenceSelector是一个内部类,其end()、current()和next()都用到了外围类中private的items字段。
2.使用.this和.new
.this的用法
如果需要生成对外部类对象的引用,可以使用外部类的名字后面紧跟圆点和this。
如下所示:
public class DotThis {
void name() {System.out.println("name");}
public class Inner{
public DotThis outer() {
return DotThis.this;
public Inner inner() {return new Inner();}
DotThis dt = new DotThis();
DotThis.Inner inner = dt.inner();
inner.outer().name();
需要注意DotThis.this只是产生了正确的外部类引用。并没有创建外部类对象。
.new的用法
可以通过该语法创建内部类对象,不过要注意的是要使用外部类的对象去创建。
public class DotNew {
public class Inner{}
DotNew dn = new DotNew();
DotNew.Inner dnInner = dn.new Inner();
内部类分类
1、局部内部类
定义在一个方法中或是方法中某一作用域内的类。称作局部内部类。
public class Product3 {
public Section section(String inputName) {
class ASection implements Section{
private String name;
private ASection(String name) {
this.name = name;
}
@Override
public String hello() {
return name + " say hello";
return new ASection(inputName);
Product3 p = new Product3();
Section section = p.section("aaaaa");
System.out.println(section.hello());
ASection是一个Section接口的实现,Section接口代码如下:
public interface Section {
String hello();
该内部类在section()方法中,该方法之外不能访问ASection类;
方法内部类不允许使用访问权限修饰符(public、private、protected);
注意方法返回的是Section 的引用,即有向上转型。
另外还可以将内部类的定义放在方法中某一语句块中,如if语句块中。
public class Product4 {
public String check(boolean flag) {
String checkId = null;
if(flag) {
class DetailCheck{
private String id;
private DetailCheck(String id) {
this.id = id;
}
String getId() {
return id;
DetailCheck dc = new DetailCheck("1111");
checkId = dc.getId();
return checkId;
Product4 p = new Product4();
//代码效果参考:http://0791zd.com/zx/art_3816.html
System.out.println(p.check(true));

DetailCheck内部类在if语句块中,因此它的作用范围也在if语句块的范围之内。超出该范围是不可用的。比如这样就会编译报错:
2、匿名内部类
匿名内部类其实是一种特殊的方法内部类(局部内部类)。它特殊在于将内部类的定义和其对象创建结合在了一块。没有通过class关键字显示声明内部类名称,故谓之“匿名”。
看代码示例:
public class Product5 {
public Section section() {
return new Section() {
private String name = "hayli";
// TODO Auto-generated method stub
return name + " haha";
};
Product5 p = new Product5();
p.section();
此处Section可以是接口,也可是基类。
3、嵌套类(静态内部类)
使用static关键字修饰的内部类,叫做静态内部类,也称作嵌套类。
嵌套类和普通内部类之间最大的区别是:
普通内部类对象隐式地保存了一个引用,指向创建它的外部类对象。而嵌套类创建对象,并不需要外部类对象。
不能从嵌套类的对象中访问非静态的外部类对象。
普通内部类不能有static数据和static字段,也不能包含嵌套类,但是嵌套类可以包含所有这些东西。
public class Product6 {
private static int id = 100;
private static class BSection implements Section{
private String name = "bbbb";
@Override
public String hello() {
return name + " hello";
// 只能访问外部类的静态数据或字段
public int getId() {return id;}

    // 可以包含静态数据或方法
    static int x = 200;
    public static void test1() {}
    // 可以再嵌套一层
    static class BInner{
        static void test1() {System.out.println("inner ===");}
    Section section = new BSection();
    section.hello();
相关文章
|
1月前
|
Java
【Java基础面试二】、个Java文件里可以有多个类吗(不含内部类)?
这篇文章讨论了Java文件中类的定义规则,指出一个Java文件可以包含多个类(不包含内部类),但其中最多只能有一个public类,且如果有public类,它的名称必须与文件名一致。
|
1月前
|
算法 Java
12 Java常用类(一)(内部类+object类+包装类)
12 Java常用类(一)(内部类+object类+包装类)
28 5
|
2月前
|
Java
Java进阶之内部类
【7月更文挑战第13天】Java内部类增进代码组织与封装,允许直接访问外部类成员,包括私有成员。主要有四种类型:成员、静态、局部和匿名内部类。匿名内部类常用于一次性实现接口或扩展类。内部类可隐藏实现细节,减少命名冲突,并在特定上下文中定义辅助类。示例展示了静态和非静态内部类如何在Shape类中封装Circle和Rectangle。使用内部类能提升代码可读性,但可能增加复杂性。
32 6
|
1月前
|
Java
【Java】内部类、枚举、泛型
【Java】内部类、枚举、泛型
|
3月前
|
Java
一篇文章讲明白Java中内部类详解—匿名内部类
一篇文章讲明白Java中内部类详解—匿名内部类
52 2
|
3月前
|
设计模式 Java 编译器
Java中的内部类(如果想知道Java中有关内部类的知识点,那么只看这一篇就足够了!)
Java中的内部类(如果想知道Java中有关内部类的知识点,那么只看这一篇就足够了!)
|
3月前
|
Java 编译器
24. 【Java教程】内部类
24. 【Java教程】内部类
23 2
|
4月前
|
Java 程序员
Java的内部类与匿名类的技术性文章
Java的内部类与匿名类的技术性文章
36 1
|
3月前
|
存储 Java
Java 五种内部类演示及底层原理详解
Java 五种内部类演示及底层原理详解
26 0
|
4月前
|
Java
Java内部类(成员内部类、静态内部类、局部内部类、局部内部类)
Java内部类(成员内部类、静态内部类、局部内部类、局部内部类)
36 3