Java内部类(成员内部类)

版权声明:未经允许转载,将保留追究其法律责任 https://blog.csdn.net/qq_37025563/article/details/86293372

概念:

  • 内部类也是一个语法糖,内部类指的就是在一个类的内部再定义一个类。

  • 内部类之所以也是语法糖,是因为它仅仅是一个编译时的概念,outer.java里面定义了一个内部类inner,一旦编译成功,就会生成两个完全不同的.class文件了,分别是outer.class和outer$inner.class。所以内部类的名字完全可以和它的外部类名字相同。

  • 内部类分为四种:
    1.成员内部类
    2.局部内部类
    3.匿名内部类
    4.静态内部类(又称嵌套类)

1.首先讲成员内部类

  • 在生成成员内部类对象时,此对象与制造它的外围对象之间就有了一种联系,所以它能访问外围对象的所有成员,此外内部类还拥有其外部内的所有元素访问权
  • 例:
public interface Selector {

    boolean end();

    Object current();

    void next();
}
public class Sequence {

    private Object [] items;

    private int next = 0;

    public Sequence(int size) {
        this.items = new Object[size];
    }

    public void add(Object item){
        if(next < items.length){
            items[next++] = item;
        }
    }

    private class SequenceSelector implements Selector{

        private int i = 0;

        @Override
        public boolean end() {
            return i == items.length;
        }

        @Override
        public Object current() {
            return items[i];
        }

        @Override
        public void next() {
            if(i < items.length){
                i++;
            }
        }
    }

    public Selector getSelector(){
        return new SequenceSelector();
    }

    public static void main(String[] args) {
        Sequence sequence = new Sequence(10);
        for (int i = 0; i < 10; i++) {
            sequence.add(Integer.toString(i));
        }
        Selector selector = sequence.getSelector();
        while (! selector.end()){
            System.out.println(selector.current());
            selector.next();
        }
    }
  • 为甚么成员内部类能够访问外部内的所有元素,是因为 当某个外围类
    创建了成员内部时候,此对象必定会秘密的捕获一个外部类的引用,然后成员内部类在访问外围类的成员时候,就是使用外围内的引用来选择外围内的成员,编译器会帮你处理所有的细节

  • 下面是成员类部类通过反编译工具的字节码文件

// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://kpdus.tripod.com/jad.html
// Decompiler options: packimports(3) fieldsfirst ansi space 
// Source File Name:   Sequence.java

package com.dongzhu.cn.prototype.test;

import java.io.PrintStream;

// Referenced classes of package com.dongzhu.cn.prototype.test:
//			Selector, Sequence

private class Sequence$SequenceSelector
	implements Selector
{

	private int i;
	final Sequence this$0;

	public boolean end()
	{
		System.out.println(Sequence.this);
		return i == Sequence.access$000(Sequence.this).length;
	}

	public Object current()
	{
		return Sequence.access$000(Sequence.this)[i];
	}

	public void next()
	{
		if (i < Sequence.access$000(Sequence.this).length)
			i++;
	}

	private Sequence$SequenceSelector()
	{
		this$0 = Sequence.this;
		super();
		i = 0;
	}

}

  
package com.dongzhu.cn.prototype.test;

import java.io.PrintStream;

public class Sequence
{
  private Object[] items;
  private int next = 0;
  
  public Sequence(int size)
  {
    this.items = new Object[size];
  }
  
  public void add(Object item)
  {
    if (this.next < this.items.length) {
      this.items[(this.next++)] = item;
    }
  }
  
  private class SequenceSelector
    implements Selector
  {
    private int i = 0;
    
    private SequenceSelector() {}
    
    public boolean end()
    {
      return this.i == Sequence.this.items.length;
    }
    
    public Object current()
    {
      return Sequence.this.items[this.i];
    }
    
    public void next()
    {
      if (this.i < Sequence.this.items.length) {
        this.i += 1;
      }
    }
  }
  
  public Selector getSelector()
  {
    return new SequenceSelector(null);
  }
  
  public static void main(String[] args)
  {
    Sequence sequence = new Sequence(10);
    for (int i = 0; i < 10; i++) {
      sequence.add(Integer.toString(i));
    }
    Selector selector = sequence.getSelector();
    while (!selector.end())
    {
      System.out.println(selector.current());
      selector.next();
    }
  }
}
  • 根据字节码文件 可以清楚的看到内部类确实是通过某种方式拿到了外围类的引用

  • 拿到成员内部类引用的两种方式


// 源码文件在上面 
Sequence sequence = new Sequence(10);

// 第一种通过.this 方式创建内部类对象
Selector selector = sequence.getSelector();
// 第二种通过.new 方式创建内部类对象
SequenceSelector sequenceSelector = sequence.new SequenceSelector();

总结:
本章主要讲了内部类概念
内部类的分类
成员内部类的用法,及原理

声明:本章节摘自与Java编程思想,在加上个人的一些观点与实践

扫描二维码关注公众号,回复: 4912536 查看本文章

猜你喜欢

转载自blog.csdn.net/qq_37025563/article/details/86293372