Java: ошибка не может найти символ - почему это ошибка, а не исключение? - PullRequest
0 голосов
/ 06 апреля 2020

Я относительно новичок в Java, и пытаюсь понять причину, по которой я сделал эту ошибку, а не исключение.

В нескольких местах я читал об ошибке:

"указывает на серьезные проблемы, которые разумное приложение не должно пытаться перехватить"

В моем случае я создал метод getAttribute, содержащий переключатель для возврата различных значений поля в зависимости от запрашиваемого атрибута. В этом случае это казалось более элегантным, чем использование методов получения для каждого из этих атрибутов. Вот пример кода:

public class JPXmlWord implements Serializable {

        private static final long serialVersionUID = 1L;

        @XmlAttribute(name = "Kanji")
        private String kanji;
        @XmlAttribute(name = "Kana")
        private String kana;
        @XmlAttribute(name = "English")
        private String english;
        @XmlAttribute(name = "Romaji")
        private String romaji;
        @XmlAttribute(name = "Katakana")
        private String katakana;
        public String getAttribute( String attribute ) throws Exception {
            switch ( attribute ) {
                case ("kanji"):
                    return this.kanji;
                case ("kana"):
                    return this.kana;
                case ("english"):
                    return this.english;
                case ("romaji"):
                    return this.romaji;
                case ("katakana"):
                    return this.katakana;
                default:
                    throw new Exception();
            } 
        }


По запросу вы можете воспроизвести ошибку отсутствующего символа (та же ошибка, что и при запросе любого отсутствующего символа из любого класса):

JPXmlWord word = new JPXmlWord();
word.getAttribute("nonExistentAttribute");

Желая выдать исключение, определяющее c, когда запрашивается несуществующее поле, я попытался запросить несуществующее поле в jshell, чтобы увидеть, какое конкретное c исключение выдается, но получило ошибку, а не исключение.

Почему запрос на несуществующее поле считается проблемой "что разумное приложение не должно пытаться его перехватить"?

Я волнуюсь, есть что-то, что я не asp о Java философия, потому что я удивлен этим. Любая помощь будет принята с благодарностью! Спасибо!

1 Ответ

2 голосов
/ 06 апреля 2020

Если я правильно вас понял, ваш код выглядит примерно так

public class Main {
    private String field1;
    private String field2;

    public String getAttribute(String name) {
        switch (name) {
            case "field1":
                return this.field1;
            case "field2":
                return this.field2;
            case "notDeclaredField":
                return this.notDeclaredField; // <- this is simply an error that the javac is telling you about
            default:
                throw new IllegalArgumentException("Invalid name");
        }
    }
}

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

class Class:
    def __init__(self):
        pass

    def setAtt(self, value):
        self.field = value # this is okay in python

С другой стороны, приведенный ниже код прекрасно скомпилируется и будет выполнять то, что вам нужно ожидайте, что

public class Main {
    private String field1;
    private String field2;

    public String getAttribute(String name) {
        switch (name) {
            case "field1":
                return this.field1;
            case "field2":
                return this.field2;
            default:
                throw new IllegalArgumentException("Invalid name");
        }
    }
}

заметит, что нет доступа к полю, которое не объявлено. Но если у вас есть фиксированный набор атрибутов, к которым вы хотите иметь доступ, вы должны просто написать геттер для каждого из них. Таким образом, вы получаете гарантию того, что поле / атрибут присутствует во время компиляции, а не во время выполнения.

Но если вы хотите иметь возможность добавлять атрибуты к вашему экземпляру класса во время выполнения, вы должны использовать Map<,> чтобы отслеживать их значения

import java.util.HashMap;

public class Main {
    private HashMap<String, String> atts = new HashMap<>();

    public String getAttribute(String name) {
        if (atts.containsKey(name)) {
            return atts.get(name);
        } else {
            throw new IllegalArgumentException("There is not attribute with the name: " + name);
        }
    }

    public static void main(String[] args) {}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...