繁体   English   中英

使用Java系统属性的最佳实践

[英]Best Practice for Using Java System Properties

我们的代码使用了很多系统属性,例如'java.io.tmpdir','user.home','user.name'等。我们没有为这些定义任何常量(我认为也不是java)或者处理它们的任何其他聪明之处,因此它们在整个代码中都是乱七八糟的文本。

String tempFolderPath = System.getProperty("java.io.tmpdir");

每个人如何使用系统属性?

我会像处理代码中的任何其他字符串常量一样对待它,并为它定义一个常量变量。 当然,在这种情况下,“java.io.tmpdir”不太可能改变,但你永远不会知道。 (我并不是说Sun可能会改变“java.io.tmpdir”的含义,或者它指向的系统属性,但是您可能会改变您对需要阅读的系统属性的看法。)

如果你只使用一个类中的特定属性,那么我将在该类中定义常量。

private final String TEMPDIR = "java.io.tmpdir";

如果您在不同的类中使用相同的属性,则可能需要定义自己的静态类来保存最常用的常量。

public final Class Prop {
    public static final String TEMPDIR = "java.io.tmpdir";
    ...
}

然后,您需要使用该常量的任何地方只需使用它

System.getProperty(Prop.TEMPDIR);

Apache Commons Lang包提供的SystemUtils解决了这个问题。

SystemUtils为大多数系统属性定义了常量,可以通过查找获得,例如:

import org.apache.commons.lang3.SystemUtils;

class Something
{
    public static void main(String[] args){     
        System.out.println(SystemUtils.JAVA_IO_TMPDIR);
    }
}

也许,这是一种更清洁的方式。

我认为在面向对象的软件中,您可能有一个对象(或方法)依赖于必须完成作业的目录。 因此,您可以证明这种依赖于构造函数或方法。 之后,如果您需要该目录的默认值并且默认来自系统属性,您可以简单地创建一个工厂方法或构造函数/方法,将较少的参数传递给另一个costrunctor /方法a:

new File(System.getProperty("java.io.tmpdir");

您不需要创建“依赖磁体”仅包含配置参数。

如果你在多个地方使用它,那么编写一个类来封装读取属性和其他属性可能是个好主意。

所以可能是这样的:Configuration.getTemporaryDirectory()

由于问题标题非常广泛,我将在使用系统属性时考虑另一个好的做法。 SecurityManager可以拒绝访问系统属性,因此您可能需要通过PrivilegedAction访问它们如下所示:

String tmpdir = AccessController.doPrivileged(new PrivilegedAction<String>() {
  public String run() {
    return System.getProperty("java.io.tmpdir");
  }
});

当代码约束敏感操作时使用特权操作,以便即使恶意代码调用它也是安全的。

例如,在诸如OutputStream open(File file)类的方法中使用特权操作是不安全的。 不受信任的代码可以调用它,并使用您的代码权限在任何地方编写任何内容。

但是,如果您有一个方法将应用程序的用户首选项保存到您选择的文件中,那么这可能是安全的。 恶意调用者无法选择文件位置或其内容; 这些是由您的代码指定的。 因此,您的方法可以使用特权操作来允许由非特权代码调用它。

我将这些视为任何其他常量,可能带有P_PROP_前缀,并将它们放在适当的常量类中。

如果你使用了很多,我甚至会考虑将它们拆分为PropertyNames常量类:

public final class PropertyNames
{
  private PropertyNames()
  {
     // no instantiation
  }

  public static final String P_VAR_DIRECTORY = "org.acme.app.varDir";

  public static final String P_TMP_DIRECTORY = "java.io.tmpDir";
}

最后,我会认真考虑使用用于包的标准反向域名来命名属性名称本身。 这只是为了避免与第三方属性消费者发生冲突。

在Java中,字符串是不可变的,这意味着内存空间中的相同对象不会被覆盖; 每次都会创建一个新的String。 目前投票最高的建议是使用常数:

System.getProperty(Prop.TEMPDIR);

不幸的是,使用的常量是实际的属性键。 这意味着每次进行此调用时,您将创建一个新的String对象来保存该值。 在我看来,你应该使调用本身的结果为常量:

public static final String SYS_PROP_TEMP_DIR = System.getProperty("java.io.tmpdir");

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM