С Math.random()
вы вызываете метод stati c. Методы Stati c не зависят от наличия экземпляра класса.
Не-stati c вызов будет:
Math math=new Math();
double m = math.random();
Но это не компилируется, потому что по умолчанию Конструктор Math является приватным.
Вы написали "Так что вызов random () вызывает конструктор randomNumberGenerator в классе", что неверно. Ключевого слова "new" нет, следовательно, нет вызова конструктора.
RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
Здесь «randomNumberGenerator» является атрибутом (переменная) c класса RandomNumberGeneratorHolder. Stati c доступ не зависит от вызова конструктора.
Java классы могут дополнительно содержать безымянный инициализатор stati c, который выполняется виртуальной машиной Java, когда класс загружается в память. Инициализатор stati c может инициализировать атрибуты stati c класса. Такой инициализатор явно заполнял атрибут stati c "randomNumberGenerator" экземпляром класса. Таким образом, вы можете вызывать метод non-stati c nextDouble()
.
Другими хорошо известными примерами являются System.out
и System.in
.
. Я приведу два примера, как запрограммируйте такой инициализатор c:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
class Main
{
static List<String> names;
static List<String> colors= Arrays.asList("red","green");
static // notice that this method has no name!
{
names=new ArrayList<String>();
names.add("CuriousIndeed");
names.add("Stefan");
}
public static void main(String[] args)
{
System.out.println(names);
System.out.println(colors);
}
}
Выходы:
[CuriousIndeed, Stefan]
[red, green]
Оба, имена и цвета были статически инициализированы, но двумя различными способами.