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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/487590/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 12:37:07  来源:igfitidea点击:

Best Practice for Using Java System Properties

javaproperties

提问by willcodejavaforfood

Our code uses a lot of system properties eg, 'java.io.tmpdir', 'user.home', 'user.name' etc. We do not have any constants defined for these anywhere (and neither does java I think) or any other clever thing for dealing with them so they are in plain text littered throughout the code.

我们的代码使用了很多系统属性,例如“java.io.tmpdir”、“user.home”、“user.name”等。我们没有在任何地方为这些定义任何常量(我认为 java 也没有)或处理它们的任何其他聪明的事情,使它们以纯文本形式散布在整个代码中。

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

How is everyone using system properties?

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

采纳答案by Bill the Lizard

I would treat this just as any other String constant you have scattered throughout your code and define a constant variable for it. Granted, in this case "java.io.tmpdir" is unlikely to change, but you never know. (I don't mean that Sun might change the meaning of "java.io.tmpdir", or what system property it points to, but that you might change your mind about what system property you need to read.)

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

If you're only using a particular property within one class, then I'd define the constants right in that class.

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

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

If you're using the same properties in different classes, you may want to define an static class of your own to hold the constants you use most often.

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

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

Then, everywhere you need to use that constant just call it using

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

System.getProperty(Prop.TEMPDIR);

回答by a3.14_Infinity

SystemUtilsprovided by Apache Commons Lang package, solves this problem.

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

SystemUtils has defined constant for most of the system properties, which can be obtained by a lookup, for example:

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

import org.apache.commons.lang3.SystemUtils;

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

Probably, that is a cleaner way to do it.

可能,这是一种更清洁的方法。

回答by sixro

I think that in an object oriented software, you have probably an object (or a method) that have a dependency on a directory where a job has to be done. So, you can put in evidence this dependency on the constructor or the method. After that, if you need a default for that directory and the default come from a system property, you can simply create a factory method or a constructor/method with less parameters passing to the other costrunctor/method a:

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

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

You don't need to create a "dependency magnet" only to contain a configuration parameter.

你不需要创建一个“依赖磁铁”来只包含一个配置参数。

回答by sixro

if you are using it in multiple places it might be a good idea to write a class to encapsulate reading the property and maybe other properties.

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

so maybe something like: Configuration.getTemporaryDirectory()

所以可能类似于:Configuration.getTemporaryDirectory()

回答by erickson

Since the question title is extremely broad, I'll throw in another good practice you should consider when using system properties. Access to system properties can by denied by the SecurityManager, so you may need to access them through a PrivilegedAction,like this:

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

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

Use a privileged action when your code constrains a sensitive action so that it will be safe even if malicious code invokes it.

当您的代码限制敏感操作时使用特权操作,这样即使恶意代码调用它也是安全的。

For example, it would be unsafe to use a privileged action in a method like OutputStream open(File file). Untrusted code could invoke it, and use your code's privileges to write anything, anywhere.

例如,在像OutputStream open(File file). 不受信任的代码可以调用它,并使用您代码的权限在任何地方编写任何内容。

However, if you had a method that saved user preferences for your application to a file you choose, that would probably be safe. A malicious caller can't choose the file location or its contents; those are specified by your code. So, your method can use a privileged action to allow it to be invoked by unprivileged code.

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

回答by jamesh

I'd treat these as any other constant, probably with a P_or PROP_prefix, and put them in an appropriate constants class.

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

If you use lots of them, I'd even consider splitting them out to a PropertyNamesconstants class:

如果您使用了很多,我什至会考虑将它们拆分为一个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";
}

Finally, I would seriously considering namespacing the property names themselves, with the standard reverse domain name used for packages. This is just to avoid clashing with third-party properties consumers.

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

回答by Cody Burleson

In Java, Strings are immutable, which means the same object in memory space is not overwritten; a new String is created every time. The currently highest voted suggestion is to use a constant:

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

System.getProperty(Prop.TEMPDIR);

Unfortunately, the constant being used is for the actual property key. That means that every time you make this call, you're going to create a new String object to hold the value. In my opinion, you should make the constant the result of the call itself:

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

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