内部类

内部类:

package innerClass;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;

/**
 * Created by admin on 2017-3-29.
 */
public class InnerClassTest {

    public static void main(String[] args) {
        TalkingClock clock = new TalkingClock(1000,true);
        clock.start();
        JOptionPane.showMessageDialog(null,"Quit program?");
        System.exit(0);
    }

}
class TalkingClock{
    private int interval;
    private boolean beep;

    public TalkingClock(int interval, boolean beep) {
        this.interval = interval;
        this.beep = beep;
    }

    public void start(){
        ActionListener listener = new TimePrinter();
        Timer t = new Timer(interval,listener);
        t.start();
    }
class TimePrinter implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println(new Date());
        if (beep){
            System.out.println("beep");
        }
    }
}

}

非内部类:

package innerClass;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;

/**
 * Created by admin on 2017-3-29.
 */
public class InnerClassTest {

    public static void main(String[] args) {
        TalkingClock clock = new TalkingClock(1000,true);
        clock.start();
        JOptionPane.showMessageDialog(null,"Quit program?");
        System.exit(0);
    }

}
class TalkingClock{
    private int interval;
    private boolean beep;

    public TalkingClock(int interval, boolean beep) {
        this.interval = interval;
        this.beep = beep;
    }

    static boolean access$000(TalkingClock talkingClock){
        return talkingClock.beep;
    }
    public void start(){
        ActionListener listener = new TimePrinter(this);
        Timer t = new Timer(interval,listener);
        t.start();
    }

}
class TimePrinter implements ActionListener{

    private TalkingClock outer;

    public TimePrinter(TalkingClock clock) {
        outer = clock;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println(new Date());
        if (TalkingClock.access$000(outer)){
            System.out.println("beep");
        }
    }
}

1.内部类可以访问该类定义所在作用域中数据,包括私有。是因为内部类的对象有一个隐式引用,他指向了创建它的外部类对象。外部类的引用在构造器中设置,构造器的参数为外部类引用。
2.内部类一种编译器现象,与虚拟机无关。编译器会把内部类翻译成用$(美元符号)分隔外部类名与内部类名的常规文件。编译器为了引用外部类,会生成一个附加的实例域this$0(名字是有编译器合成的,在自己的代码中不能引用它)。

3.内部类被翻译成名字怪异的常规类,对于域来说,每个域会自动生成一个静态方法access$000(或access$0),该方法接受所属类对象为参数,返回值传给域。可以利用这个在B类中调用A类的私有方法。

局部内部类:

package innerClass;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;

/**
 * Created by admin on 2017-3-29.
 */
public class InnerClassTest {

    public static void main(String[] args) {
        TalkingClock clock = new TalkingClock(1000,true);
        clock.start();
        JOptionPane.showMessageDialog(null,"Quit program?");
        System.exit(0);
    }

}
class TalkingClock{
    private int interval;
    private boolean beep;

    public TalkingClock(int interval, boolean beep) {
        this.interval = interval;
        this.beep = beep;
    }

    public void start(){

        class TimePrinter implements ActionListener{
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println(new Date());
                if (beep){
                    System.out.println("beep");
                }
            }
        }

        ActionListener listener = new TimePrinter();
        Timer t = new Timer(interval,listener);
        t.start();
    }


}

局部内部类不能用public或private访问说明符进行说明。它的作用域被限定在声明这个局部类的块中。优势:仅仅start方法指导该局部内部类的存在。

从外部方法访问变量:

package innerClass;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;

/**
 * Created by admin on 2017-3-29.
 */
public class InnerClassTest {

    public static void main(String[] args) {
        TalkingClock clock = new TalkingClock();
        clock.start(1000,true);
        JOptionPane.showMessageDialog(null,"Quit program?");
        System.exit(0);
    }

}
class TalkingClock{

    public void start(int interval,final boolean beep){

        class TimePrinter implements ActionListener{
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println(new Date());
                if (beep){
                    System.out.println("beep");
                }
            }
        }

        ActionListener listener = new TimePrinter();
        Timer t = new Timer(interval,listener);
        t.start();
    }


}

不仅能够访问包含他们的外部类,还可以访问局部变量。不过。局部变量必须被声明为final。(如果不设为final的话,start方法结束后,beep参数变量不复存在)。
实际上,当创建一个局部内部类对象时,ceep会被传递给构造器,并存储在val$beep域中。编译器必须检测对局部变量的访问,为每一个变量建立相应的数据域,并将局部变量拷贝到构造器中,以便将这些数据初始化为局部变量的副本(只有在构造器中调用一次,所以局部变量必须是final,不可改变的,否则很容易就不一致了)。但是有时会想要改变参数,比如计数器,考虑必须是final的,也必须是可以改变值的,所以用到了数组,final代表数组的对象不变,但是里面的只可以改变。

匿名内部类:

package innerClass;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;

/**
 * Created by admin on 2017-3-29.
 */
public class InnerClassTest {

    public static void main(String[] args) {
        TalkingClock clock = new TalkingClock();
        clock.start(1000,true);
        JOptionPane.showMessageDialog(null,"Quit program?");
        System.exit(0);
    }

}
class TalkingClock{

    public void start(int interval,final boolean beep){

        Timer t = new Timer(interval, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println(new Date());
                if (beep){
                    System.out.println("beep");
                }
            }
        });
        t.start();
    }


}

匿名内部类在jdk1.8中可以用lambda表达式来代替。
注:::t.invaite(new ArrayList<String>(){{ add.("Harry"); add("Tony");}})。双大括号初始化:外层:ArrayList的匿名类,内层:对象构造块。

静态内部类:

package innerClass;

/**
 * Created by lyj on 2017-3-30.
 */
public class ArrayAlg {


    public static void main(String[] args) {
        double[] a = new double[10];
        for(int i=0;i<a.length;i++){
            a[i] = Math.random()*100;//0-100
        }
        Pair pair = ArrayAlg.minmax(a);
        System.out.println(pair.getFirst());
        System.out.println(pair.getSecond());
    }
    public static Pair minmax(double[] values){
        double max = Double.MIN_VALUE;
        double min = Double.MAX_VALUE;
        for (double v : values) {
            if(min > v){
                min = v;
            }
            if(max < v){
                max = v;
            }
        }
        System.out.println(min);
        System.out.println(max);
        return new ArrayAlg.Pair(min,max);
    }
    public static class Pair{
        private double first;
        private double second;

        public Pair(double first, double second) {
            this.first = first;
            this.second = second;
        }

        public double getFirst() {
            return first;
        }

        public double getSecond() {
            return second;
        }
    }
}

静态内部类的对象除了没有对生成它的外部类对象的引用特权之外,与其他所有内部类完全一样。在内部类不需要访问外部类对象时,应该使用静态内部类。

注:::生命在接口中的内部类自动成为static和public类。

原文地址:https://www.cnblogs.com/wongem/p/6644402.html