Java:不推荐使用`sun.awt.image`包吗?

Mir*_*ili 5 java java-platform-module-system java-9 java-module module-info

我想要使​​用sun.awt.image.PNGImageDecoder在我的项目中使用的一些代码.问题是源代码基于Java 8和我的项目使用JDK 9+(11).所以我收到了这个错误:

包' sun.awt.image'在模块' java.desktop'中声明,它不会将其导出到未命名的模块.

import sun.awt.image.*,和:

符号在模块' java.desktop'中声明,它不导出包' sun.awt.image'

使用PNGImageDecoderImageDecoder

在寻找解决方案的一些努力之后,我发现了一些类似的情况,建议添加requires java.desktop;module-info.java文件(像这种情况这种情况).但是当我意识到这个解决方案只有在你的项目已经有一个module-info.java文件并且你遗漏了一个用过的模块时才有用.

我的项目已经没有此文件(请注意第一条错误消息中的" 未命名模块 ").据我所知,这意味着所有模块都是自动导入的.所以添加这个文件并添加该行没有任何影响,除了(更改错误消息和)导致我的代码的其他部分出现一些类似的问题(当然,这可以通过向module-info.java文件添加所需的模块来解决).

确保我在jmods文件夹(JDK 11)中导入了所有模块,但问题没有解决:

requires java.base;
requires java.compiler;
requires java.datatransfer;
requires java.desktop;
requires java.instrument;
requires java.logging;
requires java.management;
requires java.management.rmi;
requires java.naming;
requires java.net.http;
requires java.prefs;
requires java.rmi;
requires java.scripting;
requires java.se;
requires java.security.jgss;
requires java.security.sasl;
requires java.smartcardio;
requires java.sql;
requires java.sql.rowset;
requires java.transaction.xa;
requires java.xml.crypto;
requires java.xml;
requires jdk.accessibility;
requires jdk.aot;
requires jdk.attach;
requires jdk.charsets;
requires jdk.compiler;
requires jdk.crypto.cryptoki;
requires jdk.crypto.ec;
requires jdk.crypto.mscapi;
requires jdk.dynalink;
requires jdk.editpad;
requires jdk.hotspot.agent;
requires jdk.httpserver;
requires jdk.internal.ed;
requires jdk.internal.jvmstat;
requires jdk.internal.le;
requires jdk.internal.opt;
requires jdk.internal.vm.ci;
requires jdk.internal.vm.compiler;
requires jdk.internal.vm.compiler.management;
requires jdk.jartool;
requires jdk.javadoc;
requires jdk.jcmd;
requires jdk.jconsole;
requires jdk.jdeps;
requires jdk.jdi;
requires jdk.jdwp.agent;
requires jdk.jfr;
requires jdk.jlink;
requires jdk.jshell;
requires jdk.jsobject;
requires jdk.jstatd;
requires jdk.localedata;
requires jdk.management.agent;
requires jdk.management.jfr;
requires jdk.management;
requires jdk.naming.dns;
requires jdk.naming.rmi;
requires jdk.net;
requires jdk.pack;
requires jdk.rmic;
requires jdk.scripting.nashorn;
requires jdk.scripting.nashorn.shell;
requires jdk.sctp;
requires jdk.security.auth;
requires jdk.security.jgss;
requires jdk.unsupported.desktop;
requires jdk.unsupported;
requires jdk.xml.dom;
requires jdk.zipfs;
Run Code Online (Sandbox Code Playgroud)

我知道这个package(sun.awt.image)存在于java.desktop模块(JDK 11)中,但不知道如何访问它.

我使用IntelliJ IDEA作为IDE.

Nam*_*man 6

它是封装的!

这个问题肯定无法解决,包括JDK的所有模块.

我知道这个包(sun.awt.image)存在于java.desktop模块(JDK 11)中,但不知道如何访问它.

这里问题的实际症结在于,即使PNGImageDecoder它所属的类和包sun.awt.imagejava.desktop模块的一部分,模块也选择不将导出到使用它的任何外部库.

抽象这些类(sun.*)的选择是有意的,并且在Java-9的发行说明中很好地记录,并且在JEP-260#Encapsulate Most Internal API中也提到了基本原理.


话虽如此,对它的临时相当苛刻的解决方案将是补充

--add-exports=java.desktop/sun.awt.image=<yourModuleName>
Run Code Online (Sandbox Code Playgroud)

到您的命令行参数.最好是,您应该寻找另一种方法来实现您尝试使用该课程实现的目标PNGImageDecoder.


它的最后一部分,"未命名的模块"是实际代码(无论是你的应用程序还是它的任何依赖项)试图访问这个类的地方PNGImageDecoder.所以想想它,上面的命令行arg为你的用例导致:

--add-exports=java.desktop/sun.awt.image=ALL-UNNAMED
Run Code Online (Sandbox Code Playgroud)


Jes*_*per 4

您不应该在程序中使用sun.*或类;com.sun.*它们是 JDK 的未记录的内部类,并且可以在任何版本中更改。

使用它们可能会使您的程序与其他版本的 Java 不兼容。

请参阅:使用 Sun 专有的 Java 类是一种不好的做法吗?

  • 当然在一个完美的世界里,但有时你必须这样做才能把事情做好。 (3认同)
  • 当然可以,但现在您通常使用 Java 版本打包您的应用程序,这样您就可以确保您的应用程序可以与您分发它的 Java 版本配合使用。只有当阳光课程是解决问题的唯一方法时,我才会使用阳光课程,这当然不是我想做的事情。 (2认同)