使用Sun的专有Java类是一个不好的实践吗?

30

如果您使用 Sun 的专有 Java 类,编译器会显示警告。我认为通常不应该使用这些类。我在某个地方读到过这个观点。但是,除了出现警告之外,还有其他基本原因导致您不应该使用它们吗?


2
任何足够通用的功能都将体现在官方Java API中。在Sun类中是否真的有您需要的不能通过标准Java API完成的功能?您能举个例子吗? - Tendayi Mawushe
有时候我会使用内部的Xerces来处理XML。 - Andreas Dolk
1
Xerces是使用JAXP处理XML时的默认XML实现。没有必要深入使用xerces。 - Tendayi Mawushe
我发布的原因是因为我遇到了一些使用sun.misc.BASE64Decoder的代码。我将其改为使用来自apache的编解码器。我知道这样做是正确的,但记不起为什么了。 - JARC
我想抱怨那些类在 IKVM.NET 中导致80%的问题,可以一整天都在抱怨。 - Jessie Lesbian
7个回答

60

因为它们是内部API:它们可能以未记录或不支持的方式发生变化,并且它们绑定到特定的JRE / JDK(在您的情况下为Sun),限制了您程序的可移植性。

尽量避免使用这些API,始终优先选择公共记录和指定的类。


3
com.sun.* 下的一些 API 是实验性的(例如原始 APT API)。如果我没记错的话,Alex Buckley 在他的博客中介绍了这些 API 的各种状态。但总的来说,在更新版本和不同的供应商之间,它们可能会发生更改或消失。 - Tom Hawtin - tackline
1
我已经设置了我的Java编辑器(IntelliJ Idea)以从智能感知建议中排除com.sun。谢谢你的建议。 - skiabox
@TomHawtin-tackline,“APT”是指Academic Progress Tracker吗? - Franklin Yu
2
@FranklinYu 高级客运列车。不,apt 是注释处理工具。它曾经有自己的可执行文件 apt,现在是 javac 的一部分(-processor 等)。 - Tom Hawtin - tackline

24

JDK 6文档中包含一个名为Note About sun.* Packages的链接。这是来自Java 1.2文档的一份文件,因此对sun.*的引用应视为对com.sun.*的引用。

其中最重要的几点是:

Sun随Java 2 SDK、标准版一起提供的类属于包组java.*javax.*org.*sun.*。除了sun.*包外,其他所有包都是Java平台的标准部分,并且将得到支持。通常,诸如sun.*之类的在Java平台之外的包可能会因为操作系统平台(Solaris、Windows、Linux、Macintosh等)而不同,并且可以在SDK版本(1.2、1.2.1、1.2.3等)中随时更改而没有通知。包含对sun.*包的直接调用的程序不是100%纯Java。

以及

每个实现Java平台的公司都会以自己的方式进行。sun.*中的类存在于SDK中,以支持Java平台的Sun实现:这些sun.*类是使Java平台类在Sun Java 2 SDK下“在幕后”工作的关键。这些类通常不会出现在另一个供应商的Java平台上。如果您的Java程序按名称请求“sun.package.Foo”类,则可能会失败并出现ClassNotFoundError,并且您将失去使用Java开发的主要优势。

6
作为“几年后”的评论:不能保证 com.sun.* 不会变成 com.oracle.*,因为 Sun 公司已经不存在了。 - Powerlord
4
不正确。许多com.sun.*包是文件化规范的一部分。没有它们将无法编写JNDI LDAP或COSNaming代码。问题在于sun.*包,这是一个完全不同的问题,并且有明确的文档说明。 - user207421
3
顺便提一下,在Java 9中尝试使用sun.*com.sun.*类将会失败得非常惊人。 - Powerlord
5
不是com.sun.*类。它们是Sun/Oracle JDK的已记录部分。 - user207421
我知道 sun.* 是内部的,但是有没有关于 com.sun.* 是内部的任何来源?并且有没有任何版本中 com.sun.* 包出现问题的例子? - Franklin Yu
相关:com.sun包里面有什么? - Franklin Yu

10

尝试使用非Sun JVM运行你的代码,看看会发生什么...

(你的代码将因为ClassNotFound异常而失败)


4
这是一个有效的建议来鉴定问题(虽然不是正式答案)。 - Esko
5
非常实用的例子,能够生动形象地展示大多数人认为是一个假想的未来问题。+1 - Brian

7

是的,因为没有人能保证这些类或API在下一个Java版本中仍然保持不变,我敢打赌这些类在其他供应商的Java版本中也可能不可用。

所以你把你的代码与特定的Java版本联系起来,至少会失去可移植性。


4

Sun公司的专有Java类是他们的Java实现的一部分,而不是Java API的一部分,它们的使用未经记录和不受支持。由于它们是内部的,因此Sun JVM团队随时可以出于任何原因更改它们。

此外,Sun的Java实现并不是唯一的!您的代码将无法在其他供应商(如Oracle/BEA和IBM)的JVM上移植。


2

4
虽然这个回答从理论上回答了问题,但最好包括关键部分的答案并提供链接作为参考。 - BoltClock

1
最近我遇到了一个案例,展示了在使用这些类时可能会遇到的现实问题:我们的代码无法编译,因为它正在使用 sun.* 类上的一个方法,在 Ubuntu 上的 OpenJDK 中根本不存在。所以我想当你使用这些类时,你不能再说像“这适用于Java 5”这样的话了,因为它只能在某个特定的Java实现上工作。

我强烈建议在不同的平台和JVM上运行单元测试,而不是使用开发时的环境。很多有趣的问题往往会浮出水面。 - Thorbjørn Ravn Andersen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接