Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java编译-有没有办法告诉编译器忽略部分代码?_Java_Swing_Compilation - Fatal编程技术网

Java编译-有没有办法告诉编译器忽略部分代码?

Java编译-有没有办法告诉编译器忽略部分代码?,java,swing,compilation,Java,Swing,Compilation,我维护一个JavaSwing应用程序 为了向后兼容Java5(对于Apple机器),我们维护了两个代码库,一个使用Java6的特性,另一个没有这些特性 除了使用Java6特性的3-4类之外,代码基本相同 我希望只维护1个代码库。在编译过程中,有没有办法让Java5编译器“忽略”我代码的某些部分 根据java编译器的版本,我不想简单地注释/取消注释部分代码。我认为最好的方法可能是使用构建脚本。您可以将所有代码放在一个位置,通过选择要包含和不包含的文件,您可以选择要编译的代码版本。请注意,如果您需要

我维护一个JavaSwing应用程序

为了向后兼容Java5(对于Apple机器),我们维护了两个代码库,一个使用Java6的特性,另一个没有这些特性

除了使用Java6特性的3-4类之外,代码基本相同

我希望只维护1个代码库。在编译过程中,有没有办法让Java5编译器“忽略”我代码的某些部分


根据java编译器的版本,我不想简单地注释/取消注释部分代码。

我认为最好的方法可能是使用构建脚本。您可以将所有代码放在一个位置,通过选择要包含和不包含的文件,您可以选择要编译的代码版本。请注意,如果您需要比每个文件更细粒度的控制,这可能没有帮助。

实际上没有,但有一些解决方法。看见

也就是说,您应该坚持至少有一个Java5文件版本和一个Java6文件版本,并根据需要通过构建或制作来包含它们。将所有内容都放在一个大文件中,并试图让编译器忽略它不理解的内容,这不是一个好的解决方案


--nikki--

这会让所有Java纯粹主义者畏缩(这很有趣,嘿嘿),但我会使用C预处理器,在我的源代码中添加ifdefs。makefile、rakefile或任何控制构建的东西都必须运行cpp来生成一个临时文件以提供给编译器。我不知道蚂蚁是否能做到这一点


虽然stackoverflow看起来将是一个提供所有答案的地方,但您可以看到,没有人在寻找Java智慧。我想这个问题很久以前就已经在那里讨论过了。

Java中没有预编译器。因此,没有办法像C中那样做ifdef。
构建脚本将是最好的方法。

您可以获得条件编译,但不是很好-javac将忽略无法访问的代码。因此,如果代码结构正确,编译器可以忽略部分代码。为了正确地使用它,您还需要将正确的参数传递给javac,以便它不会将无法访问的代码报告为错误,并拒绝编译:-)

保留一个在JDK 5下构建的“主”源根。添加第二个必须在JDK 6或更高版本下构建的并行源根。(应该没有重叠,即两者中都没有类。)使用接口定义两者之间的入口点,以及一点点反射

例如:

---%<--- main/RandomClass.java
// ...
if (...is JDK 6+...) {
    try {
        JDK6Interface i = (JDK6Interface)
            Class.forName("JDK6Impl").newInstance();
        i.browseDesktop(...);
    } catch (Exception x) {
        // fall back...
    }
}
---%<--- main/JDK6Interface.java
public interface JDK6Interface {
    void browseDesktop(URI uri);
}
---%<--- jdk6/JDK6Impl.java
public class JDK6Impl implements JDK6Interface {
    public void browseDesktop(URI uri) {
        java.awt.Desktop.getDesktop().browse(uri);
    }
}
---%<---

--%您可以重构代码,这样就不需要条件编译,只需要条件类加载。大概是这样的:

public interface Opener{

public void open(File f);

 public static class Util{
        public Opener getOpener(){
          if(System.getProperty("java.version").beginsWith("1.5")){
           return new Java5Opener();
          }
          try{ 
            return new Java6Opener();
           }catch(Throwable t){
            return new Java5Opener();
           }
        }
 }

}

这可能需要很大的努力,具体取决于您拥有多少特定于版本的代码片段。

假设这些类具有类似的功能,在实现上有1.5和6.0的差异,您可以将它们合并到一个类中。然后,无需编辑源代码以进行注释/取消注释,您就可以依靠编译器经常进行的优化。如果If表达式始终为false,则If语句中的代码将不包括在编译中

您可以在一个类中创建一个静态变量,以确定要运行的版本:

public static final boolean COMPILED_IN_JAVA_6 = false;
然后让受影响的类检查该静态变量,并将代码的不同部分放入一个简单的if语句中

if (VersionUtil.COMPILED_IN_JAVA_6) {
  // Java 6 stuff goes here
} else {
  // Java 1.5 stuff goes here
}

然后,当您想要编译另一个版本时,您只需更改该变量并重新编译。它可能会使java文件变大,但它会整合您的代码并消除所有代码重复。您的编辑器可能会抱怨无法访问的代码或其他问题,但编译器应该很高兴地忽略它。

上面提到的公共静态最终解决方案还有一个作者没有提到的好处——据我所知,编译器将在编译时识别它,并编译出引用最终变量的if语句中的任何代码


因此,我认为这正是您所寻求的解决方案。

一个简单的解决方案可能是:

  • 将分歧类放置在正常类路径之外
  • 编写一个简单的自定义类加载器,并将其作为默认值安装在main中
  • 对于除5/6类以外的所有类,cassloader可以遵从其父类(普通系统类加载器)
  • 对于5/6个(应该是父级无法找到的唯一一个),它可以通过“os.name”属性或您自己的属性来决定使用哪个

这取决于您希望使用的Java 6功能。对于向JTables添加行分类器这样的简单操作,您实际上可以在运行时测试:

private static final double javaVersion =
         Double.parseDouble(System.getProperty("java.version").substring(0, 3));
private static final boolean supportsRowSorter =
         (javaVersion >= 1.6);

//...

if (supportsRowSorter) {
    myTable.setAutoCreateRowSorter(true);
} else {
    // not supported
}
这段代码必须用Java6编译,但可以用任何版本运行(没有引用新类)


编辑:更准确地说,它将适用于自1.3版以来的任何版本(根据)。

关于使用自定义类加载器和动态注释代码的建议在涉及到维护和维护任何一个可怜的灵魂的健全性时,都有点令人怀疑,因为在你重新开始新的项目后,他们会选择该项目


解决办法很简单。将受影响的类拖出到两个独立的项目中——确保包名相同,然后编译成JAR,然后在主项目中使用。如果保持包名相同,方法签名相同,那么没有问题——只需将所需的jar版本放到部署脚本中即可。我假设您运行单独的构建脚本,或者在同一个脚本中有单独的目标—ant和maven都可以轻松地处理有条件地获取和复制文件。

您可以只在Java6上进行编译,然后使用System.getProperty(“java.version”)有条件地运行Java5或Java6代码路径

在一个应用程序中,只能使用Java6代码