Есть ли преимущества использования статического импорта перед импортом?
Рассмотрим следующий класс
public final class Constant {
public static final String USER_NAME="user1";
//more constant here
}
Этот класс в пакете Б.
Теперь я собираюсь использовать это в пакете А. Рассмотрим следующие два способа, которые можно использовать.
Способ 1- использование import B.Constant
import B.Constant;
public class ValidateUser {
public static void main(String[] args) {
if(Constant.USER_NAME.equals("user1")){
}
}
}
Способ 2- использование import static B.Constant.USER_NAME;
import static B.Constant.USER_NAME;
public class ValidateUser {
public static void main(String[] args) {
if(USER_NAME.equals("user1")){
}
}
}
Мой вопрос: есть ли разница или преимущество обычного импорта по сравнению со статическим в этом случае?
8 ответов
Единственная разница между нормальным import
и import static
является то, что последний для перемещения static
члены некоторого другого класса или интерфейса - особенно константы - в область видимости. Вам решать, используете ли вы это; Мне нравится это, потому что это держит тело класса короче, но YMMV.
Нет никакого преимущества в производительности или штрафов за их использование (за исключением, возможно, при компиляции, как если бы вы заботились об этом), поскольку они компилируются в идентичный байт-код.
Основным отличием является читаемость, Constant.USER_NAME
менее читабелен по сравнению с USER_NAME
,
Из документации:
При правильном использовании статический импорт может сделать вашу программу более читабельной, удалив шаблон повторения имен классов.
Но в любом случае старайтесь избегать
import static B.Constant.*;
потому что он может загрязнить свое пространство имен всеми статическими членами, которые вы импортируете.
Я использую статический импорт очень редко и только там, где он на самом деле облегчает выполнение кода.
Согласно оракулу:
http://docs.oracle.com/javase/1.5.0/docs/guide/language/static-import.html
Итак, когда вы должны использовать статический импорт? Очень экономно! Используйте его только тогда, когда у вас возникнет искушение объявить локальные копии констант или злоупотреблять наследованием (Антипаттерн Constant Interface). Другими словами, используйте его, когда вам требуется частый доступ к статическим членам одного или двух классов. Если вы чрезмерно используете функцию статического импорта, она может сделать вашу программу нечитаемой и не поддерживаемой, загрязняя ее пространство имен всеми импортируемыми вами статическими элементами. Читатели вашего кода (включая вас через несколько месяцев после того, как вы его написали) не будут знать, из какого класса происходит статический член. Импорт всех статических членов из класса может быть особенно вредным для читабельности; если вам нужен только один или два участника, импортируйте их по отдельности. При правильном использовании статический импорт может сделать вашу программу более читабельной, удалив шаблон повторения имен классов.
Важные моменты, чтобы отметить здесь:
- Используйте его, когда вам требуется частый доступ к статическим членам одного или двух классов
- При правильном использовании статический импорт может сделать вашу программу более читабельной
И комментатор @Donal Fellows говорит, что использование IDE для управления статическим импортом менее рискованно. Я согласен с тем, что современные IDE прошли долгий путь и избавят вас от многих трудностей, связанных с управлением зависимостями и отслеживанием обращений к родителям.
Например, все методы в классе Math являются статическими, и мы вызываем их все как Math.mathod(). Но если мы импортируем математический класс следующим образом: import static java.lang.Math.*;
Нам не нужно добавлять Math перед методом:
import static java.lang.Math.*;
public class Program {
public static void main(String args[]) {
System.out.println(sqrt(25));
System.out.println(log(100));
System.out.println(PI);
}
}
Статический импорт позволяет избежать определения статических членов именами классов.
Как только статический член импортирован, вы можете использовать его в своем коде без префикса имени класса.
Хороший пример:
import static sample.SampleStaticValues.NUM_ZERO;
…
enum OddEven {odd,even}
//need not do SampleConstants.NUM_ZERO due to static import feature
if(num % 2 == NUM_ZERO){
System.out.println("The num " + num + " is: " + OddEven.even);
}
package sample;
public class SampleStaticValues {
public static int NUM_ZERO = 0;
public static int NUM_ONE = 0;
}
Ребята, сегодня мы столкнулись с большим недостатком статического импорта. Просто делюсь этим ниже.
- XXXConsts.java имел EVENT_ID (EVENT_ID = "EVENT_ID"), который был статически импортирован в класс XXXComceteImpl.java, который происходит от AbstractService.java
- XXXZeloImpl.java, который расширяется от AbstractService.java wanted EVENT_ID = "eventId". Поэтому EVENT_ID = "eventId" был объявлен в AbstractService.java.
- Теперь #1 был сломан, поскольку EVENT_ID в XXXComceteImpl.java ссылался на EVENT_ID в AbstractService.java
- Возможно, имя EVENT_ID = "eventId" должно было быть другим.
- Примечание:- Названия классифицированной версии отредактированы, поэтому она выглядит необычно.
Статический импорт используется для экономии вашего времени и набора текста. Если вам не нравится вводить одно и то же снова и снова, такой импорт может оказаться интересным.
Импорт позволяет программисту Java получать доступ к классам пакета без квалификации пакета.
Функциястатического импорта позволяет получить доступ к статическим членам класса без квалификации класса.
Давайте разберемся с помощью приведенных ниже примеров:
Пример 1: без статического импорта
class Demo1{
public static void main(String args[])
{
double var1= Math.sqrt(5.0);
double var2= Math.tan(30);
System.out.println("Square of 5 is:"+ var1);
System.out.println("Tan of 30 is:"+ var2);
}
}
Выход:
Square of 5 is:2.23606797749979
Tan of 30 is:-6.405331196646276
Пример 2. Использование статического импорта
import static java.lang.System.out;
import static java.lang.Math.*;
class Demo2{
public static void main(String args[])
{
//instead of Math.sqrt need to use only sqrt
double var1= sqrt(5.0);
//instead of Math.tan need to use only tan
double var2= tan(30);
//need not to use System in both the below statements
out.println("Square of 5 is:"+var1);
out.println("Tan of 30 is:"+var2);
}
}
Выход:
Square of 5 is:2.23606797749979
Tan of 30 is:-6.405331196646276
Чтобы получить доступ к статическим членам, необходимо квалифицировать ссылки в соответствии с классом, из которого они получены. Например, нужно сказать:
double r = Math.cos(Math.PI * theta);
or
System.out.println("Blah blah blah");
Вы можете избежать ненужного использования статических членов класса, таких как Math. и система. Для этого используйте статический импорт. Например, приведенный выше код при изменении с помощью статического импорта изменяется на:
import static java.lang.System.out;
import static java.lang.Math.PI;
import static java.lang.Math.cos;
...
double r = cos(PI * theta);
out.println("Blah blah blah");
...
Так в чем же преимущество использования вышеуказанной техники? Единственное преимущество, которое я вижу, - читаемость кода. Вместо написания имени статического класса можно напрямую написать имя метода или переменной-члена. Также имейте в виду одну вещь здесь. Неоднозначный статический импорт не допускается. т.е. если вы импортировали java.lang.Math.PI и хотите импортировать mypackage.Someclass.PI, компилятор выдаст ошибку. Таким образом, вы можете импортировать только один элемент PI.