2014-05-23 174 views
3

我正在读一些关于Java类的内容,并且介绍了静态初始化。但是,当您只能首先设置默认值时,我无法看到使用它们的要点。 例如,Java - 静态初始化与静态变量的默认值

static int a; 
static { 
    a = 5; 
} 

static int a = 5 
在类定义

这两者有区别吗?如果不是,你什么时候使用静态初始值与默认值?

回答

4

没有区别。

什么时候你会使用静态初始值与默认值?

当评估表达式的代码更复杂时,尤其是涉及异常时。

static int a ; 
static { 
    String x = System.getProperty("abc"); 
    try{ 
     a = Integer.parseInt(x); 
    } 
    catch (Exception e){ 
     throw new IllegalArgumentException 
      ("missing or invalid system property 'abc': "+x); 
    } 
} 

但是,最好将代码移动到私有静态方法中。

final static int a = complexCalculation(); 
2

有这两者之间有区别吗?

没有在您发布的示例中。但是,static {}形式可以包括任意代码包括循环,try/catch语句等

如果没有,什么时候使用静态初始化与默认值?

当你需要额外的功能。

1

如果内存服务,没有有效的区别。但是,静态块有助于提高可读性或执行需要多个步骤的任务。从大学一年级就拿这个(不好)例如:

// Pattern of initial memory values, used during critter file parsing 
private static Pattern memoryMatcher; 
private static Pattern sugarMatcher; 
private static Pattern generalMemoryMatcher; 
// Block to create memoryMatcher 
static { 
    final StringBuilder builder = new StringBuilder(); 

    // Append each of the sugar values, separated by a pipe 
    builder.append("(?i)("); 
    for (final Sugar sugar : Sugar.values()) { 
     builder.append(sugar.toString()); 
     builder.append("|"); 
    } 

    // Replace final pipe with close parenthesis and create sugarMatcher 
    sugarMatcher = Pattern.compile(builder.replace(
      builder.length() - 1, builder.length(), ")").toString()); 

    // Append some stuff to catch ": <number>" and whitespace, then 
    // create memoryMatcher 
    memoryMatcher = Pattern.compile(builder.insert(4, "(") 
      .insert(builder.length() - 1, "|mem\\[-?\\d+\\]") 
      .append(":\\s*-?\\d*|\\s*)").toString()); 

    // Should match mem[<number>] 
    generalMemoryMatcher = Pattern.compile("mem\\[-?\\d+\\]"); 
} 

此前的Java 8中,涉及for循环,我不相信将能够作为一个单一的任务的一部分工作的代码。虽然Java 8的流将允许我将其作为作业的一部分来执行此操作,但memoryMatchersugarMatcher的工作将复制一些工作,这并不是真正需要的。

0
Is there a difference between these two? 

没有,在这种情况下,你共享

如果没有代码,什么时候使用静态初始化与默认值?

有许多场景,你需要静态初始化器,例如,如果你的应用程序只需要一个对象的实例。您可以使用静态块来实现如何获取单个实例的逻辑。

1

Is there a difference between these two?

没有,在这种情况下是没有区别的,如你的静态初始化块,你只是在一些非常复杂的场景值分配给一个variable.But这可能并非如此。

If not, when would you use static initializers versus default values?

这种运作良好,当初始化值可用并且 初始化一行可以放。但是,这种初始化形式由于其简单性而具有局限性。如果 初始化需要某些逻辑(例如,错误处理或用于填充复杂数组的循环),则简单分配是不充分的。

静态初始化块是用大括号括起来的正常的代码块,并且以static关键字开头。下面是一个例子:

static { 
    // whatever code is needed for initialization goes here 
} 

一个类可以有任意数量的静态初始化块,它们可以出现在类体中的任何地方。运行时系统保证静态初始化块按它们出现在源代码中的顺序被调用。

有静态块一个选择 - 你可以写一个私有静态方法:

class Whatever { 
    public static varType myVar = initializeClassVariable(); 

    private static varType initializeClassVariable() { 

     // initialization code goes here 
    } 
} 

的私有静态方法的好处是,如果你需要重新初始化类变量,他们以后可以重复使用。

0

没有区别。实际上,编译器会将简短的表单变为一个声明加上静态的块。如果你在结果类上运行“javap”,它们是相同的。

JDK中带有编译器的“javap”工具是查看代码并确切知道“有什么不同”的好方法!

public class Test { 

    //static int a= 5; 

    static int a; 
    static { 
     a = 5; 
    } 

} 

的javap -c的Test.class

Compiled from "Test.java" 
public class Test { 
    static int a; 

    static {}; 
    Code: 
     0: iconst_5 
     1: putstatic  #10     // Field a:I 
     4: return 

    public Test(); 
    Code: 
     0: aload_0 
     1: invokespecial #15     // Method java/lang/Object."<init>":()V 
     4: return 
}