我们的代码使用了很多系统属性,例如'java.io.tmpdir','user.home','user.name'等。我们没有为这些定义任何常量(也没有java I)思考)或处理它们的任何其他聪明的东西,所以它们在整个代码中散布着纯文本。
String tempFolderPath = System.getProperty("java.io.tmpdir");
每个人如何使用系统属性?
答案 0 :(得分:8)
我会像处理代码中的任何其他字符串常量一样对待它,并为它定义一个常量变量。当然,在这种情况下,“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);
答案 1 :(得分:5)
SystemUtils解决了这个问题。
SystemUtils为大多数系统属性定义了常量,可以通过查找获得,例如:
import org.apache.commons.lang3.SystemUtils;
class Something
{
public static void main(String[] args){
System.out.println(SystemUtils.JAVA_IO_TMPDIR);
}
}
或许,这是一种更清洁的方式。
答案 2 :(得分:4)
如果你在多个地方使用它,那么编写一个类来封装读取属性和其他属性可能是个好主意。
所以可能是这样的:Configuration.getTemporaryDirectory()
答案 3 :(得分:4)
我认为在面向对象的软件中,您可能有一个对象(或方法)依赖于必须完成作业的目录。因此,您可以证明这种依赖于构造函数或方法。 之后,如果您需要该目录的默认值并且默认值来自系统属性,则可以简单地创建一个工厂方法或构造函数/方法,将较少的参数传递给另一个costrunctor /方法a:
new File(System.getProperty("java.io.tmpdir");
您不需要创建“依赖磁铁”只包含配置参数。
答案 4 :(得分:3)
由于问题标题非常广泛,我将在使用系统属性时考虑另一个好的做法。 SecurityManager
可以拒绝访问系统属性,因此您可能需要通过PrivilegedAction
,访问它们,如下所示:
String tmpdir = AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
return System.getProperty("java.io.tmpdir");
}
});
当您的代码约束敏感操作时使用特权操作,以便即使恶意代码调用它也是安全的。
例如,在OutputStream open(File file)
之类的方法中使用特权操作是不安全的。不受信任的代码可以调用它,并使用您的代码权限在任何地方编写任何内容。
但是,如果您的方法将应用程序的用户首选项保存到您选择的文件中,那么这可能是安全的。恶意调用者无法选择文件位置或其内容;这些是由您的代码指定的。因此,您的方法可以使用特权操作来允许由非特权代码调用它。
答案 5 :(得分:1)
我将这些视为任何其他常量,可能带有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";
}
最后,我会认真考虑使用用于包的标准反向域名来命名属性名称本身。这只是为了避免与第三方媒体消费者发生冲突。
答案 6 :(得分:0)
在Java中,字符串是不可变的,这意味着内存空间中的相同对象不会被覆盖;每次都会创建一个新的String。目前投票最高的建议是使用常数:
System.getProperty(Prop.TEMPDIR);
不幸的是,正在使用的常量是实际的属性键。这意味着每次进行此调用时,您将创建一个新的String对象来保存该值。在我看来,你应该使调用本身的结果保持不变:
public static final String SYS_PROP_TEMP_DIR = System.getProperty("java.io.tmpdir");