Внутренний класс и строковые литералы в Java - PullRequest
2 голосов
/ 03 ноября 2011

Следующие два случая, кажется, работают:

public class A {
    private class B {
        public static final String str = "str";
    }
}

public class A {
    private static class B {
        public static final String str = new String("str");
    }
}

Но выдает ошибку, указанную в комментарии:

public class A {    
    private class B {
    //The field str cannot be declared static; 
    //static fields can only be declared in static or top level types
        public static final String str = new String("str"); 
    }
}

Почему это разрешено в первых двух случаях и почему оно вызывает проблему в последнем?

Ответы [ 3 ]

4 голосов
/ 03 ноября 2011

Это требуется для JLS, раздел 8.1.3 . Я никогда не видел причины для этого, но я подозреваю, что внутренний класс, который не является статическим, требует экземпляра внешнего класса, но объявляет как статическое нарушение этой концепции, и, позволяя им, он создает целый другой набор правил для обработки как раз тот случай, который считался не стоящим. Принимая во внимание, что когда он статический, он действительно похож на любой другой класс, который просто находится в том же исходном файле.

1 голос
/ 03 ноября 2011

Я предполагаю, что ограничение связано с тем, как реализовано new String("str").Инициализация члена с литеральной строкой может быть выполнена с записями в постоянном пуле, но new String("str") требует фактического выполнения кода, поэтому это должно быть выполнено с фактическими байтовыми кодами в статическом методе init.

Внутренний винтСхема классов вызывает у меня головную боль, когда я просто думаю об этом (это на самом деле внутренняя ошибка), поэтому я не могу точно объяснить, в чем проблема, но я подозреваю, что статический метод init запускается в неподходящее время в ситуации, описанной выше, поэтому либорезультаты не являются надежными, иначе система не сможет обработать исключения, возникающие из-за ошибок в статическом методе init.

0 голосов
/ 03 ноября 2011

JLS четко заявляет об этом ограничении;см. ответ Ишаи.

Одно из возможных объяснений "почему" состоит в том, что было бы ожидание, что неконстантное выражение статического инициализатора может ссылаться на статические или нестатические в классе включения.Первое потенциально может привести к концептуальным или реализационным трудностям при упорядочении классовой (статической) инициализации.Второе было бы невыполнимым и привело бы к ошибке компиляции, которую было бы трудно понять.(Подумайте, как часто новички путаются из-за статического / нестатического ограничения доступа простыми методами.)

Я думаю, что они просто пошли по простому пути и запретили это.(KISS работает для меня ...) Они, возможно, думали, что могли бы ослабить ограничение в более поздней редакции, но тогда не видели необходимости делать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...