You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java 8升级至Java 17编译报错:com.sun.java.swing.plaf.windows包不存在

Java 8 迁移至 Java 17 编译问题解决方案

一、com.sun.java.swing.plaf.windows 包无法导入的问题

Java 9引入模块系统(JPMS)后,com.sun.*这类内部API被标记为非公开,Java 17进一步强化了访问限制——即使禁用--release选项,编译器也会拒绝直接引用这些未公开的包,因为它们不在JDK默认的模块导出范围内。

解决办法:

  • 推荐方案:使用类名字符串设置LookAndFeel
    无需导入内部类,直接通过全类名字符串调用UIManager,完全规避内部API的引用:
    UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    
  • 备选方案:反射加载类(若需获取Class对象)
    如果业务逻辑必须获取该类的Class实例,可通过反射实现:
    Class<?> lafClass = Class.forName("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    UIManager.setLookAndFeel(lafClass.getName());
    
  • 不推荐方案:强制导出内部包
    虽然可以添加编译器参数--add-exports java.desktop/com.sun.java.swing.plaf.windows=ALL-UNNAMED强制让编译器识别该包,但内部API无版本兼容性承诺,后续JDK版本升级可能再次出现问题,甚至API被移除,因此不建议使用。

二、ComboPopup.getList() 泛型签名不兼容问题

Java 17中ComboPopup的getList()方法被泛型化,从原始类型JList改为JList<Object>,旧代码中重写为JList<T>的实现违反了泛型重写的类型匹配规则,导致编译失败。

解决办法:

  • 修改重写方法签名,添加安全类型转换
    对齐新的方法签名,通过类型转换保证功能正常,同时添加注解消除编译器警告:
    @SuppressWarnings("unchecked")
    @Override
    public JList<Object> getList() {
        return (JList<Object>) itemList;
    }
    
    由于Java泛型采用类型擦除机制,JList<T>和JList<Object>在运行时的实际类型一致,这个转换是安全的。
  • 调整类泛型声明(可选)
    若实现类本身带有泛型参数,可调整类定义以匹配新的方法签名逻辑:
    public class CustomComboPopup<T> implements ComboPopup {
        private JList<T> itemList;
    
        @SuppressWarnings("unchecked")
        @Override
        public JList<Object> getList() {
            return (JList<Object>) itemList;
        }
    }
    

关于Java向后兼容性的说明

Java的向后兼容性仅针对官方公开API(如java.*、javax.*包下的内容),com.sun.*这类内部API从未被纳入公开API范畴,官方一直明确禁止开发者直接依赖,其变更或访问限制不属于破坏向后兼容性的范畴。

内容的提问来源于stack exchange,提问作者Heneh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 00:42:45