关于static内部类的细节

请先看这个程序:http://algs4.cs.princeton.edu/13stacks/Bag.java.html
菜鸟提问,为什么内部类声明成了static?有什么作用么?

static关键字内部类,目的是告诉虚拟机只有一份变量声明。
private static class Node {
private Item item;
private Node next;
}
这段代码其实不论在bag当前文件内,还是由一个别的java文件单独声明,虚拟机不会因为当前bag实例的不同时间点的初始化单独创建一份了。
但这里这样写还有一个别的目的,就是在用到bag这个类的时候才告诉虚拟机“node这个类只要初始化一次”就可以了。
如果将node这个类以单独文件,那么虚拟机在启动java运行时就执行了“node这个类只要初始化一次”这样的操作了。
详细设计上写法的区别也就是上面的区别。目的就是用到的时候才声明去解释一些事情。希望这样的描述对你有用。

内部类声明为静态类,就可以直接通过外部类.内部类名来访问了,比较方便

按照下面的描述创建三个文件,给你解释的例子,希望你能理解到位。

----com.bag1test.Bag1.java

package com.bag1test;

import java.util.Iterator;

@SuppressWarnings("hiding")
public class Bag implements Iterable{

public long sid = 0;
private int N;               // number of elements in bag
private Node<String> first;    // beginning of bag

public static class Node<String> {

    private String item;
    private Node<String> next;
    public String uid = (String) "空的";

    public Node(long sid){
        uid = (String) (sid + "-" +System.currentTimeMillis());
    }
}

public Bag() {
    first = null;
    N = 0;
    sid = System.currentTimeMillis();
}

public boolean isEmpty() {
    return first == null;
}

public int size() {
    return N;
}

public void add(String item) {
    Node<String> oldfirst = first;
    first = new Node<String>(sid);
    first.item = item;
    first.next = oldfirst;
    N++;
}

@Override
public Iterator<String> iterator() {
    // TODO Auto-generated method stub
    return null;
}

}

----com.bag2test.Bag1.java

package com.bag2test;

import java.util.Iterator;
import java.util.NoSuchElementException;

@SuppressWarnings("hiding")
public class Bag implements Iterable{

public long sid = 0;
private int N;               // number of elements in bag
private Node<String> first;    // beginning of bag
public Bag() {
    first = null;
    N = 0;
    sid = System.currentTimeMillis();
}

public boolean isEmpty() {
    return first == null;
}

public int size() {
    return N;
}

public void add(String item) {
    Node<String> oldfirst = first;
    first = new Node<String>(sid);
    first.item = item;
    first.next = oldfirst;
    N++;
}

@Override
public Iterator<String> iterator() {
    return null;
}

}

--com.bag2test.Node.java

package com.bag2test;

public class Node {

public String item;
public Node<String> next;
public String uid = (String) "空的";

public Node(long sid){
    uid = (String) (sid + "-" +System.currentTimeMillis());
}

}

----ClassTester.java

public class ClassTester {

public static boolean hasClass(String className) throws Exception{
    boolean ok = true;
    try {
        Class<?> cls = Class.forName(className);
        ok = cls!=null;
    }catch (ClassNotFoundException e1) {
        ok = false;
    }catch (Exception e1) {
        ok = false;
        throw e1;
    }
    return ok;
}

//bag1test测试
public static void main(String[] args) {
    try {
        System.out.println("进程启动");
        boolean ok1 = ClassTester.hasClass("com.bag1test.Bag.Node");
        System.out.println("进程启动时虚拟机有Node类吗:"+ok1);

        com.bag1test.Bag bag = new com.bag1test.Bag();
        boolean ok2 = ClassTester.hasClass("com.bag1test.Bag.Node");
        System.out.println("加载了一个bag类后虚拟机有Node类吗:"+ok2);

        com.bag1test.Bag.Node cmd = new com.bag1test.Bag.Node(0);
        boolean ok3 = ClassTester.hasClass("com.bag1test.Bag.Node");
        System.out.println("加载了一个bag子类后虚拟机有Node类吗:"+ok3+"-"+cmd.uid);

        System.out.println("说明了啥,知道了吗-----内置类管你是静态动态的,虚拟机压根一开始都不认");
    } catch (Exception e) {
        e.printStackTrace();
    }
}

// //bag2test测试
// public static void main(String[] args) {
// try {
// System.out.println("进程启动");
// boolean ok1 = ClassTester.hasClass("com.bag2test.Node");
// System.out.println("进程启动时虚拟机有Node类吗:"+ok1);
//

// com.bag2test.Bag bag = new com.bag2test.Bag();
// boolean ok2 = ClassTester.hasClass("com.bag2test.Node");
// System.out.println("加载了一个bag类后虚拟机有Node类吗:"+ok2);
//

// System.out.println("说明了啥,知道了吗------虚拟机一开始就认了,以后爱咋用咋用");
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
}