Создание глобальной переменной или создание экземпляра внутри функции

Это не вопрос кодирования, это связано с концепцией кодирования. У меня есть класс обслуживания с некоторыми методами, а также у этого класса есть следующие 2 частных метода для анализа и проверки URL-адресов.

private boolean isUrlFormatValid(String url) {
        Pattern pattern = Pattern.compile("^(https?:\/\/)?(www\\.)?([\\w]+\\.)+[\u200C\u200B\\w]{2,63}\/?$");
        Matcher matcher = pattern.matcher(url);
        if (matcher.matches()) {
            return true;
        } else {
            LOG.error("Url format is not valid");
            return false;
        }
    }

    private String parseUrlDomain(String url) throws Exception {
        Pattern p = Pattern.compile("^(?:https?:\/\/)?(?:www\\.)?((?:[\\w]+\\.)+\\w+)");
        Matcher m = p.matcher(url);
        if (m.matches()) {
            System.out.println(m.group(1));
            return m.group(1);
        }
        throw new Exception("Url domain is not parsed ");
    }

Эти коды работают хорошо, но я не уверен в некоторых моментах, например:

1-Как вы видите, оба метода имеют общие коды, создавая экземпляры шаблон и сопоставитель. Должен ли я создать их экземпляр в начале класса как глобальную переменную? Если да, то в чем причина и в чем преимущество.

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

Следовательно, есть ли лучшая практика для этого? Заранее спасибо.

Если они не меняются, почему бы не объявить их константами, как private static final String? Или даже перечисление?

Hovercraft Full Of Eels 17.12.2018 12:45

Поправка по терминологии. Пункт 1 - это не глобальные переменные. Это переменные экземпляра, если они относятся к экземпляру объекта. Если они являются общими для всех экземпляров класса, они будут статическими переменными.

Jason Armstrong 17.12.2018 12:46
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
2
182
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

Ответ принят как подходящий

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

private static final String REGEX = "some_regex";
private static final Pattern PATTERN = Pattern.compile(REGEX);

private boolean testRegex(String s) {
    return PATTERN.matcher(s).matches();
}

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

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

один пункт; Я буду использовать эту строку и шаблон регулярного выражения только в этом классе, так в чем причина объявления его статическим? а также регулярные выражения различаются в двух методах, поэтому мне нужно объявить 2 разных экземпляра шаблона в начале класса?

abidinberkay 17.12.2018 13:14

Взгляните на ключевое слово static в Java: статические переменные экземпляра используются совместно объектами одного класса. У вас может быть 1000 объектов вашего класса, но только один экземпляр Pattern. Поскольку он потокобезопасен, его можно использовать в разных потоках.

Glains 17.12.2018 13:35

И да, вам нужно создать два объекта Pattern, если регулярные выражения разные.

Glains 17.12.2018 13:35

Я буду использовать эти регулярные выражения только один раз, поэтому мне нужно сделать их статическими? или просто создайте приватный финал ....

abidinberkay 17.12.2018 13:37

Что значит использовать их только один раз?

Glains 17.12.2018 13:38

Я просто использую эти шаблоны и регулярные выражения только один раз в своем методе. Например, у меня есть функция isUrlFormatValid (), и я использую шаблон и регулярное выражение только в этом методе. нигде более.

abidinberkay 17.12.2018 13:53

Да, но если вы вызовете этот метод несколько раз, это уже имеет значение, поскольку Pattern не нужно создавать несколько раз.

Glains 17.12.2018 14:13

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

ZhaoGang 17.12.2018 14:13
  1. Ваш шаблон основан на определенном регулярном выражении, это не значит, что у вас есть только одно регулярное выражение. Так что лучше, если вы получите выкройку по мере необходимости. Опять же, что касается Matcher, он основан на вашем шаблоне. Итак, вы создали его по мере необходимости. Сделать их переменными уровня класса будет иметь смысл, если у вас есть только одно регулярное выражение для проверки вашего URL.
  2. Для ошибок - обычно вы генерируете исключение (выдает Exception - второй случай), когда вы хотите, чтобы вызывающий API позаботился о сценарии исключения. Предположим, есть два вызывающих parseUrlDomain и эти вызывающие хотят обрабатывать исключение синтаксического анализа URL по-разному, тогда имеет смысл иметь предложение throws. С другой стороны, когда вы очень четко понимаете, как следует обрабатывать случаи ошибок или исключений, вы обычно ловите, регистрируете. (первый случай в вашем фрагменте кода.)

У меня есть 2 разных регулярных выражения, поэтому логично ли создавать шаблоны отдельно в методах, как в примере? или я должен создать 2 разных экземпляра шаблона в начале класса?

abidinberkay 17.12.2018 13:28

Создавайте их на уровне класса.

Rax 17.12.2018 13:38

Другие вопросы по теме