Если не использовать статическое ключевое слово в Java?

Агностик языка метакодирует тогда...

rev = StringReverse(originalString)
return ( rev == originalString );
29
задан Jonik 12 July 2016 в 19:53
поделиться

9 ответов

Одна из причин, по которой вы можете не захотеть, чтобы он был статическим, - это возможность переопределить его в подклассе. Другими словами, поведение может зависеть не от данных внутри объекта, а от точного типа объекта. Например, у вас может быть общий тип коллекции со свойством isReadOnly , которое будет возвращать false в всегда изменяемых коллекциях, true в всегда неизменяемых коллекциях, и зависят от переменных экземпляра в других.

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

33
ответ дан 28 November 2019 в 00:38
поделиться

Два величайших зла, с которыми вы когда-либо столкнетесь в крупномасштабных Java-приложениях, - это

  • Статические методы, за исключением тех, которые являются чистыми функциями *
  • Изменяемые статические поля

Эти разрушения модульность, расширяемость и тестируемость вашего кода до такой степени, что я понимаю, что не могу надеяться убедить вас в этом ограниченном времени и пространстве.

* «Чистая функция» - это любой метод, который не изменяет какое-либо состояние и чей результат не зависит ни от чего, кроме предоставленных ему параметров. Так, например, любая функция, которая выполняет ввод-вывод (прямо или косвенно), не является чистой функцией, но Math.sqrt (), конечно, таковой.

Еще больше о чистых функциях (self-link ) и почему вы хотите их придерживаться.

Я настоятельно рекомендую вам отдать предпочтение стилю программирования «внедрение зависимостей», возможно, поддерживается такими фреймворками, как Spring или Guice (отказ от ответственности: я являюсь соавтором последнего). Если вы сделаете это правильно, вам, по сути, никогда никогда не понадобится изменяемое статическое состояние или не чистые статические методы.

48
ответ дан 28 November 2019 в 00:38
поделиться

В общем, я предпочитаю методы экземпляра по следующим причинам:

  1. статические методы затрудняют тестирование, потому что их нельзя заменить,
  2. статические методы более ориентированы на процедуры.

На мой взгляд, статические методы подходят для служебных классов (например, StringUtils ), но я предпочитаю по возможности избегать их использования.

24
ответ дан 28 November 2019 в 00:38
поделиться

То, что вы говорите, в некотором роде верно, но что произойдет, если вы захотите переопределить поведение этого метода в производном классе? Если он статический, вы не можете этого сделать.

В качестве примера рассмотрим следующий класс типа DAO:

class CustomerDAO {
    public void CreateCustomer( Connection dbConn, Customer c ) {
       // Some implementation, created a prepared statement, inserts the customer record.
    }

    public Customer GetCustomerByID( Connection dbConn, int customerId ) {
       // Implementation
    }
}

Теперь ни один из этих методов не требует какого-либо «состояния». Все, что им нужно, передается в виде параметров. Так что они МОГУТ легко быть статичными. Теперь появляется требование, что вам необходимо поддерживать другую базу данных (скажем, Oracle)

Поскольку эти методы не являются статическими, вы можете просто создать новый класс DAO:

class OracleCustomerDAO : CustomerDAO {
    public void CreateCustomer( Connection dbConn, Customer c ) {
        // Oracle specific implementation here.
    }

    public Customer GetCustomerByID( Connection dbConn, int customerId ) {
        // Oracle specific implementation here.
    }
}

Этот новый класс теперь можно использовать вместо Старый. Если вы используете внедрение зависимостей, это может даже не потребовать изменения кода.

Но если бы мы сделали эти методы статическими, это сделало бы все намного сложнее, насколько мы можем »

4
ответ дан 28 November 2019 в 00:38
поделиться

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

0
ответ дан 28 November 2019 в 00:38
поделиться

Верно. В самом деле, вы должны преобразовать то, что в противном случае могло бы быть разумным (чтобы некоторые функции не были связаны с классом), в термины Java. Вот почему вы видите универсальные классы, такие как FredsSwingUtils и YetAnotherIOUtils.

0
ответ дан 28 November 2019 в 00:38
поделиться

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

Для меня есть два недостатка в использовании статических методов:

  1. Они делают код менее модульным и труднее тестировать / расширять. Большинство ответов уже касались этого, поэтому я больше не буду вдаваться в подробности.
  2. Статические методы, как правило, приводят к некоторой форме глобального состояния, что часто является причиной коварных ошибок. Это может происходить в плохо написанном коде, который написан для второй цели, описанной выше. Позвольте мне уточнить.

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

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

Чтобы избежать этих проблем, разработчикам следует избегать хранения каких-либо состояние с помощью статических методов и переменных. Вместо этого им следует создавать чистые API, которые позволят пользователям управлять состоянием и изолировать его по мере необходимости. BerkeleyDB является здесь хорошим примером, инкапсулируя состояние через объект Environment вместо статических вызовов.

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

Чтобы избежать этих проблем, разработчикам следует избегать хранения каких-либо состояние с помощью статических методов и переменных. Вместо этого им следует создавать чистые API, которые позволят пользователям управлять состоянием и изолировать его по мере необходимости. BerkeleyDB является здесь хорошим примером, инкапсулируя состояние через объект Environment вместо статических вызовов.

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

Чтобы избежать этих проблем, разработчикам следует избегать хранения каких-либо состояние с помощью статических методов и переменных. Вместо этого им следует создавать чистые API-интерфейсы, которые позволят пользователям управлять состоянием и изолировать его по мере необходимости. BerkeleyDB является здесь хорошим примером, инкапсулируя состояние через объект Environment вместо статических вызовов.

разработчикам следует избегать хранения любого состояния с помощью статических методов и переменных. Вместо этого им следует создавать чистые API-интерфейсы, которые позволят пользователям управлять состоянием и изолировать его по мере необходимости. BerkeleyDB является здесь хорошим примером, инкапсулируя состояние через объект Environment вместо статических вызовов.

разработчикам следует избегать хранения любого состояния с помощью статических методов и переменных. Вместо этого им следует создавать чистые API-интерфейсы, которые позволят пользователям управлять состоянием и изолировать его по мере необходимости. BerkeleyDB является здесь хорошим примером, инкапсулируя состояние через объект Environment вместо статических вызовов.

1
ответ дан 28 November 2019 в 00:38
поделиться

Дополнительное раздражение по поводу статических методов: нет простого способа передать ссылку на такую ​​функцию без создания класса-оболочки вокруг нее. Например, что-то вроде:

FunctorInterface f = new FunctorInterface() { public int calc( int x) { return MyClass.calc( x); } };

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

Незначительное замечание, но еще кое-что к не , например, о бесплатных статических функциях, то есть методах.

0
ответ дан 28 November 2019 в 00:38
поделиться

Здесь два вопроса 1) A статический метод, который создает объекты, остается загруженным в память при первом обращении к нему? Разве это (оставшаяся загруженная в память) не является недостатком? 2) Одним из преимуществ использования Java является функция сборки мусора - разве мы не игнорируем это, когда используем статические методы?

0
ответ дан 28 November 2019 в 00:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: