“导入”关键字实际上并没有导入什么。基本上它只是一种通过类名引用类的完整路径的方法。所以当我们说
import java.lang.String;
然后我们可以在我们的代码中通过它的名字“String”来引用那个类。在编译时,任何我们拥有类“String”的地方都会被替换为“java.lang.String”。而已。
这也是为什么,如果你有一个以上的类具有相同的名称,但在不同的包,你可以输入最多只是其中之一。其他课程必须以其全名。
走上问题:
1.确实的A.class存储有关其自身内部乙的一些信息?只是名称,被调用的方法,使用的最终变量?如果编译后的A.class中没有太多有关B的信息 - 为什么我们不能编译没有B.class的A?
不是真的。当您调用其他类时,类A将只使用完全限定的类名称和方法签名。使用我们的字符串例如,调用
mystring.charAt(0)
将编译成字节码是这样看的东西:
aload_1 [myString]
iconst_0
invokevirtual java.lang.String.charAt(int)
其他类的任何内部状态被存储在我们的A类里面除了内联可能常量。因此,如果价值可能在未来发生变化,请务必在字段public final
上注意。 (参见下面的解决方法)
当我们编译A类时,我们需要B.class
,因此编译器可以确保类B具有我们要使用的那些方法。
2.如果我们在与B.class包这是另外一个人更换B.class - 当它工作,何时不? 新B.class会工作,如果完全限定域名(包装等)是相同的,它具有我们正在尝试使用正确的方法签名。新的B类可以添加新的方法,甚至可以使用不同的方法实现。但是,它不能修改我们使用的方法的方法签名。如果旧方法不再存在或者其签名不同,我们将在编译时得到一个java.lang.LinkageError
。
3.如果A.class与新的B.class运行正常,那么A.class可以使用来自OLD B.class的一些信息,它在编译过程中并入A.class中?即我们最终是否可以在我们的项目中使用B.class的混合逻辑?从老B.这
唯一的问题可能是内联常量就是为什么Java Coding Guidelines项目31项(第115页)说:“不要使用公共决赛,其值在以后的版本可能恰克常量”。 相反,做一个getter方法: 例如:
class BadFoo{
//bad, VERSION could be inlined
//and later when we change the version, other classes will have the old value!
public static final int VERSION =1;
}
class BetterFoo{
private static int version =1;
//outside classes must call method getVersion()
//field version can not be inlined at compile time.
//JIT may inline at runtime which is OK
public static final int getVersion(){
return version;
}
}
4.关于上述问题的答案筑底:我们能以某种方式编译类依赖于其他类的不知道他们在编译时确切的实现,并提供依赖只在运行时?
是,代码接口。
接口应该包含所有你需要调用的方法。我们的A类应该只能通过接口引用调用者。如果我们要调用的对象实例被传入,那么类A不知道(或者需要知道)实际类型是什么,并且在编译时不需要知道它。
这是主要目的和Dependency Injection
优势之一甚至除了依赖注入,编码到接口方面具有优势。例如,如果我们使用Map
而不是HashMap
,稍后我们可以通过更改代码中的一个位置来更改代码以使用不同的Map实现,例如ConcurrentHashMap
。我们其余的代码将会工作,因为它只知道它是一个Map。
是不是“编程接口”是关于什么? – 2014-10-16 19:36:10