Относительно вопроса (1): ответ от Джона верен, поскольку он неявно помечает класс как «Вложенный» как закрытый, не делая его открытым или внутренним :-). Вы также можете сделать это явно, добавив «private»:
private class Nested
Относительно вопроса (2): в основном, что говорится в посте beforeinitfield и инициализации типов , что если у вас нет статического конструктора, среда выполнения может инициализировать его в любое время (но до его использования). Если у вас есть статический конструктор, ваш код в статическом конструкторе может инициализировать поля, что означает, что среде выполнения разрешено инициализировать поле только при запросе типа.
Поэтому, если вы не хотите, чтобы среда выполнения инициализировала поля «проактивно» перед их использованием, добавьте статический конструктор.
В любом случае, если вы реализуете синглтоны, вы хотите, чтобы он инициализировался как можно более лениво, а не тогда, когда среда выполнения думает, что должна инициализировать вашу переменную - или вам, вероятно, просто все равно. От вашего вопроса, я полагаю, вы хотите их как можно позже.
Это приводит к встрече Джона о синглтоне , который является основной темой этого вопроса. Ох и сомнения :-)
Я хотел бы отметить, что его синглтон № 3, который он пометил как «неправильный», на самом деле правильный (потому что блокировка автоматически подразумевает барьер памяти при выходе ). Он также должен быть быстрее, чем синглтон # 2, когда вы используете экземпляр более одного раза (что более или менее является точкой синглтона :-)). Так что, если вам действительно нужна ленивая одноэлементная реализация, я бы, вероятно, пошел на это - по тем простым причинам, что (1) всем ясно, что читает ваш код, что происходит, и (2) вы знаете, что произойдет за исключением
Если вам интересно: я бы никогда не использовал синглтон # 6, потому что это может легко привести к тупикам и неожиданному поведению с исключениями. Для получения дополнительной информации см .: режим блокировки lazy , в частности, ExecutionAndPublication.