Почему вызов конструктора не отображается при использовании «step into» в Eclipse даже без пошагового фильтра - PullRequest
0 голосов
/ 16 февраля 2020

Я пытаюсь понять, как Math.random () генерирует случайное число. Поэтому я использовал отладчик eclipse и функцию «шаг в».

Когда я устанавливаю точку останова на

        double mathRandom = Math.random();

и использую "step into", это переводит меня в Math.class с кодом:

public static double random() {
    return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
}

Так что вызов random () вызывает конструктор randomNumberGenerator в классе RandomNumberGeneratorHolder, который находится в классе Math.

Конструктор randomNumberGenerator также находится в классе Math в строке

private static final class RandomNumberGeneratorHolder {
    static final Random randomNumberGenerator = new Random();
}

Но когда я использую «шаг в» в строке

public static double random() {
    return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
}

Почему это не переводить меня в конструктор

private static final class RandomNumberGeneratorHolder {
    static final Random randomNumberGenerator = new Random();
}

Но вместо этого переводит меня в класс Random к строке

public double nextDouble() {
    return (((long)(next(26)) << 27) + next(27)) * DOUBLE_UNIT;
}

У меня отключен параметр "Использовать пошаговые фильтры". Так по какой причине eclipse пропускает вызов конструктора

static final Random randomNumberGenerator = new Random()

1 Ответ

1 голос
/ 16 февраля 2020

С 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]

Оба, имена и цвета были статически инициализированы, но двумя различными способами.

...