Необезопасные поля не должны быть статическими, ошибка сонара - PullRequest
0 голосов
/ 27 апреля 2018

Привет, у меня есть этот пример кода со мной.

 public class Util implements Serializable {


        private static final SimpleDateFormat DATE_KEY_FORMAT = new SimpleDateFormat("yyyyMMdd");
        private static final SimpleDateFormat EUS_WS_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
        private static final SimpleDateFormat DATETIME_KEY_FORMAT = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        public static final String TIME_ZONE_GMT = "GMT";


        /**
         * Returns date in the format yyyyMMdd
         * @return
         */
        public static int getyyyyMMdd() {
            return Integer.parseInt(DATE_KEY_FORMAT.format(new Date()));
        }

        public static int getyyyyMMdd(Date date) {
            return Integer.parseInt(DATE_KEY_FORMAT.format(date));
        }

        public static String getyyMMdd(Date dateTime) {
            return DATE_KEY_FORMAT.format(dateTime);
        }

        public static String getyyyyMMddHHmmssSSSCur(Date dateTime) {
            return DATETIME_KEY_FORMAT.format(dateTime);
        }

если я удаляю статические из строки: private static final SimpleDateFormat DATE_KEY_FORMAT = new SimpleDateFormat("yyyyMMdd"), то как получить к ним доступ не статичным образом? потому что он показывает ошибку в следующем фрагменте кода:

public static int getyyyyMMdd() {
        return Integer.parseInt(DATE_KEY_FORMAT.format(new Date()));
    }

Может ли кто-нибудь подсказать, как получить к нему доступ после снятия статики? заранее спасибо

Ответы [ 3 ]

0 голосов
/ 27 апреля 2018

Удаление static не делает его потокобезопасным: экземпляры могут быть доступны из отдельных потоков одновременно.

Попробуйте использовать ThreadLocal<SimpleDateFormat>:

private static final ThreadLocal<SimpleDateFormat> DATE_KEY_FORMAT =
    ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyyMMdd"));

, а затем получить доступ в статических методах следующим образом:

return Integer.parseInt(DATE_KEY_FORMAT.get().format(new Date()));

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

Однако изменения в SimpleDateFormat (например, установка часового пояса) будут сохраняться в данном потоке до тех пор, пока вы не вызовете DATE_KEY_FORMAT.remove(). Но если вы никогда не вносите такие изменения в экземпляр, вам не нужно об этом беспокоиться.

0 голосов
/ 27 апреля 2018

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

Например, для некоторого класса вы вызываете метод util getyyyMMdd () без создания экземпляра переменной экземпляра.

    public class SomeClass() {

       public SomeClass(){}

       public printDateInYears() {
           System.out.println(Util.getyyyyMMdd());
       }

    }

Единственный способ получить доступ к переменной экземпляра - сделать метод getyyyyMMdd () не статичным.

0 голосов
/ 27 апреля 2018

Экземпляр SimpleDateFormat не является потокобезопасным и поэтому не должен иметь одновременного доступа.
Вы должны создать методы экземпляров статических методов, поскольку статические методы не могут получить доступ к членам экземпляра.
Также обратите внимание, что при одновременном доступе к методам у вас возникнет та же проблема параллелизма. Таким образом, в многопоточной среде вы должны создать экземпляр SimpleDateFormat внутри каждого метода (который может быть дорогим) или (менее дорогой) добавить единственный экземпляр SimpleDateFormat в ThreadLocal.

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