Три вещи:
- У второго есть дополнительный вызов, что означает, что он может изменить результат.Это может быть плохо, а может и нет, но это то, что нужно учитывать.Посмотрите пример того, как это может работать.
- Второй создает дополнительный объект.Это плохо.
- Второе подразумевает, что вы вызываете метод для объекта, а не для самого класса, что сбивает с толку людей, которые его читают.Это тоже плохо.Посмотрите пример того, как это может быть очень плохо!
Рассмотрим следующую причину 1:
class ClassName {
static int nextId;
static int m() { return nextId; }
int id;
ClassName() { id = nextId; nextId++; }
/**
C:\junk>java ClassName
2
2
3
*/
public static void main(String[] args) {
new ClassName();
new ClassName();
System.out.println(ClassName.m());
System.out.println(ClassName.m());
System.out.println((new ClassName()).m());
}
}
Рассмотрим следующее, добавив причину 2, на которую ссылается @emory:
class ClassName {
// perhaps ClassName has some caching mechanism?
static final List<ClassName> badStructure = new LinkedList<ClassName>();
ClassName() {
// Note this also gives outside threads access to this object
// before it is fully constructed! Generally bad...
badStructure.add(this);
}
public static void main(String[] args) {
ClassName c1 = new ClassName(); // create a ClassName object
c1 = null; // normally it would get GC'd but a ref exist in badStructure! :-(
}
}
Рассмотрим следующую причину 3:
class BadSleep implements Runnable {
int i = 0;
public void run() {
while(true) {
i++;
}
}
public static void main(String[] args) throws Exception {
Thread t = new Thread(new BadSleep());
t.start();
// okay t is running - let's pause it for a second
t.sleep(1000); // oh snap! Doesn't pause t, it pauses main! Ugh!
}
}