问题描述
- 关于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();
// }
// }
}