我们一直希望我们的开发/测试环境像生产环境一样,但是经常会陷入使用JDK函数的陷阱中,这些函数没有非常明确地暴露环境依赖性(例如必需的方法参数),或者可能难以发现和察觉。例如:

  • public String(byte bytes[])使用默认编码
  • new Date()/Instant.now()使用系统时区
  • System.out.printf("%n")使用平台行结尾

  • 其中一些可以由JVM参数(如-Dfile.encoding=UTF-8)驱动。

    但是如何找到所有这些陷阱呢?

    最佳答案

    陷阱的类型取决于您的应用程序的类型。

    对于几乎完整的列表,您可以运行此检查,该检查同时列出了操作系统环境变量和java系统属性:

    import java.awt.GraphicsEnvironment;
    import java.util.Map;
    import java.util.Properties;
    
    public class Sof39189179 {
    
        public static void main(String[] args) {
    
            Map<String, String> sysenv = System.getenv();
    
            for(String key: sysenv.keySet())
                System.out.println( key +  ": " + sysenv.get(key));
    
            Properties properties = System.getProperties();
    
            for(Object key: properties.keySet())
                System.out.println(key + ": " + properties.get(key));
    
            GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
            System.out.println("headless: " + ge.isHeadless());
        }
    }
    

    在我的计算机上,我得到以下输出(我省略了一些行):
    M2: $M2_HOME/bin
    JAVA_HOME: /opt/local/jdk-1.8.0_51
    LANG: en_US.UTF-8
    CATALINA_HOME: /opt/local/tomcat-8.0.24
    
    ...
    
    ---------------------
    java.runtime.name: Java(TM) SE Runtime Environment
    sun.boot.library.path: /opt/local/jdk-1.8.0_51/jre/lib/amd64
    java.vm.version: 25.51-b03
    java.vm.vendor: Oracle Corporation
    java.vendor.url: http://java.oracle.com/
    path.separator: :
    java.vm.name: Java HotSpot(TM) 64-Bit Server VM
    file.encoding.pkg: sun.io
    user.country: US
    sun.java.launcher: SUN_STANDARD
    sun.os.patch.level: unknown
    java.vm.specification.name: Java Virtual Machine Specification
    user.dir: /home/rudolf/workspace/neon/sof39189179
    java.runtime.version: 1.8.0_51-b16
    java.awt.graphicsenv: sun.awt.X11GraphicsEnvironment
    java.endorsed.dirs: /opt/local/jdk-1.8.0_51/jre/lib/endorsed
    os.arch: amd64
    java.io.tmpdir: /tmp
    line.separator:
    
    java.vm.specification.vendor: Oracle Corporation
    os.name: Linux
    ...
    
    java.awt.printerjob: sun.print.PSPrinterJob
    file.encoding: UTF-8
    java.specification.version: 1.8
    java.class.path: /home/rudolf/workspace/neon/sof39189179/bin
    user.name: rudolf
    java.vm.specification.version: 1.8
    java.home: /opt/local/jdk-1.8.0_51/jre
    sun.arch.data.model: 64
    user.language: en
    java.specification.vendor: Oracle Corporation
    awt.toolkit: sun.awt.X11.XToolkit
    java.vm.info: mixed mode
    java.version: 1.8.0_51
    java.ext.dirs: /opt/local/jdk-1.8.0_51/jre/lib/ext:/usr/java/packages/lib/ext
    sun.boot.class.path: /opt/local/jdk-1.8.0_51/jre/lib/resources.jar:/opt/local/jdk-1.8.0_51/jre/lib/rt.jar:/opt/local/jdk-1.8.0_51/jre/lib/sunrsasign.jar:/opt/local/jdk-1.8.0_51/jre/lib/jsse.jar:/opt/local/jdk-1.8.0_51/jre/lib/jce.jar:/opt/local/jdk-1.8.0_51/jre/lib/charsets.jar:/opt/local/jdk-1.8.0_51/jre/lib/jfr.jar:/opt/local/jdk-1.8.0_51/jre/classes
    java.vendor: Oracle Corporation
    file.separator: /
    java.vendor.url.bug: http://bugreport.sun.com/bugreport/
    sun.io.unicode.encoding: UnicodeLittle
    sun.cpu.endian: little
    sun.cpu.isalist:
    headless: false
    

    您可以从此列表中确定与您的情况相关的属性,然后检查代码。或者,最好在编写代码时要牢记这些属性。



    我更喜欢使用上面列出的属性,即为了打印换行符,我使用类似以下内容:
    String newline = (String) System.getProperties().get("line.separator");
    System.out.println("newline: " +  newline);
    

    关于java - 如何在JDK中找到平台相关陷阱的完整列表,例如时区,编码,行尾等?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39189179/

    10-14 15:33