这是回复[url=http://www.cnblogs.com/JeffreyZhao/archive/2010/02/22/why-not-csharp-on-jvm-type-erasure.html#1767075]这个回复[/url]的帖。放个例子来说明Java的package与JAR包的关系(或者说没关系?)
Java/JVM要认定某两个类型是否属于同一个runtime package,只需要看这两个类型是不是由同一个classloader加载的、并且package的全限定名完全一样;跟这两个类型是从什么地方加载过来的没关系。
举例说明。假设有这样的目录结构:
B.java为:
Main.java为:
通过下面步骤来编译:
可以看到编译没任何问题。
现在目录结构变为:
然后执行Main:
运行没任何问题。说明在不同JAR包里的A与B之间能互相“找到”,Main也能找到它们俩;A与B仍然在同一个runtime package中。
相关代码都放在附件里了。
Java/JVM要认定某两个类型是否属于同一个runtime package,只需要看这两个类型是不是由同一个classloader加载的、并且package的全限定名完全一样;跟这两个类型是从什么地方加载过来的没关系。
举例说明。假设有这样的目录结构:
│ Main.java
│
└─ab
└─cd
└─ef
A.java
B.java[/code]
其中A.java为:
[code="java">package ab.cd.ef;
public class A {
public B makeB() {
return new B();
}
}
B.java为:
package ab.cd.ef;
public class B {
}
Main.java为:
import ab.cd.ef.A;
import ab.cd.ef.B;
public class Main {
public static void main(String[] args) {
B b = new A().makeB();
System.out.println(b);
}
}
通过下面步骤来编译:
D:\testpackage>javac ab/cd/ef/A.java
D:\testpackage>jar cvf myjar1.jar ab/cd/ef/A.class
标明清单(manifest)
增加:ab/cd/ef/A.class(读入= 277) (写出= 202)(压缩了 27%)
D:\testpackage>jar cvf myjar2.jar ab/cd/ef/B.class
标明清单(manifest)
增加:ab/cd/ef/B.class(读入= 185) (写出= 159)(压缩了 14%)
D:\testpackage>javac -classpath "myjar1.jar;myjar2.jar" Main.java
可以看到编译没任何问题。
现在目录结构变为:
│ Main.class
│ Main.java
│ myjar1.jar
│ myjar2.jar
│
└─ab
└─cd
└─ef
A.class
A.java
B.class
B.java[/code]
此时A.class与B.class分别分布在myjar1.jar与myjar2.jar中。
为了避免嫌疑,把ab/cd/ef里的.class文件都删除掉,变为:
[code="">D:\TESTPACKAGE
│ Main.class
│ Main.java
│ myjar1.jar
│ myjar2.jar
│
└─ab
└─cd
└─ef
A.java
B.java
然后执行Main:
D:\testpackage>java -classpath ".;myjar1.jar;myjar2.jar" Main
ab.cd.ef.B@1fb8ee3
运行没任何问题。说明在不同JAR包里的A与B之间能互相“找到”,Main也能找到它们俩;A与B仍然在同一个runtime package中。
相关代码都放在附件里了。