据我所知,在Java的编译期间,只记录了类/方法签名。实际的实现在JVM中绑定到运行时间。
让我们假设有一个名为MyClass
的原生 Java类。在Java 1.6版本中:
public class NativeClass {
public String getVersion() { return "1.6"; }
}
在Java 1.7版中:
public class NativeClass {
public String getVersion() { return "1.7"; }
public String somethingMore() { return "more"; }
}
我们的IDE和编译器是1.7。在编译程序之后,当我们在JRE 1.6和1.7中运行它时,我们将从NativeClass.getVersion();
获得不同的返回值。这是众所周知的。
但是如果我们在JRE 1.6上运行NativeClass.somethingMore()
会怎样?
如果可能的话,请在真正的Java源代码中举例说明,其中某些类/方法仅存在于较新的版本中。
答案 0 :(得分:2)
但是如果我们在JRE 1.6上运行NativeClass.somethingMore()会发生什么?
如果应用程序试图调用类的指定方法(静态或实例),并且该类不再具有该方法的定义,则抛出该异常。
如果一个课程不存在怎么办?没有
NoSuchClassError
见NoClassDefFoundError
& ClassNotFoundException
但不要问我a)为什么有两个。 b)为什么一个用于另一个/差异是什么,或c)为什么方法也有NoSuchMethodException
。
它们似乎都应该是Error
而不是Exception
。
答案 1 :(得分:1)
第一点是,如果使用Java 1.7 SDK(或IDE)编译代码,并尝试在Java 1.6(或更早版本)上运行代码,则可能会遇到“幻数” “错误。基本上,除非将“目标版本”设置为旧版本,否则编译器将发出旧JVM无法理解的字节码文件。
一旦你完成了这个:
尝试调用不存在的方法将导致NoSuchMethodError
。
尝试使用(以任何方式)不存在的类将导致ClassDefNotFoundError
。
当JVM尝试解析类之间的依赖关系时,会检测并抛出错误。 (这在JLS中称为“链接”。它发生在类“初始化”之前的某个时间,但是JVM可以自由地实现加载和链接延迟,因此它可能不会立即在应用程序启动时发生。
这两个都是致命错误。它们使JVM处于应用程序不可能恢复的状态,因为应用程序的基本类的不确定集不可用。
这些是“二进制兼容性错误”的示例。其他示例包括缺少字段,具有错误签名的方法,访问修饰符中的一些更改,继承层次结构的更改等等。 (有一个完整的JLS章节涉及二进制兼容性规则;即在不破坏兼容性的情况下,您可以在一个类中进行更改,也可以不进行更改。)
这真的是常识。如果你试图调用一个不在那里的方法或者使用一个不在那里的类,那么用一个致命的错误拯救是唯一安全的事情。 “一次写入,随处运行”有实际限制。
如果您想要一个简单示例,请尝试在Java 1.5或更早版本的JVM上运行使用String.isEmpty()
的应用程序。 (或早期发布Android手机......)
你不会得到ClassNotFoundException
。只有在尝试使用Class.forName(...)
加载类时才会抛出此内容。
答案 2 :(得分:0)
此代码适用于最新的MySQL JDBC驱动程序 - mysql-connector-5.1.22
Connection conn = DriverManager.getConnection"jdbc:mysql://localhost:3306/test", "root", "root");
conn.getSchema();
但如果我使用旧版本,例如mysql-connector-5.1.20,我会得到
Exception in thread "main" java.lang.AbstractMethodError: com.mysql.jdbc.JDBC4Connection.getSchema()Ljava/lang/String;
at main.MySQL.main(MySQL.java:21)
因为Connection.getSchema
是1.7以来。
如果缺少具体课程,例如。 Integer.compare(int,int)从1.7开始就会得到java.lang.NoSuchMethodError
如果缺少JRE课程,例如java.util.Scanner从1.5开始,我使用的是JRE 1.4,我会得到java.lang.NoClassDefFoundError