Какая польза от частной статической переменной в Java?

156

Если переменная объявлена ​​как public static varName;, то я могу получить к ней доступ откуда угодно ClassName.varName. Мне также известно, что статические члены совместно используются всеми экземплярами класса и не перераспределяются в каждом экземпляре.

Объявление переменной private static varName;отличается от объявления переменной private varName;?

В обоих случаях к нему нельзя получить доступ ClassName.varNameили как ClassInstance.varNameот любого другого класса.

Объявляет ли переменная как статическую другие специальные свойства?

Вайбхав Яни
источник
5
Имена переменных Java не могут содержать тире (-).
Мартин Курто

Ответы:

127

Конечно, к нему можно получить доступ как ClassName.var_name, но только из класса, в котором он определен, - потому что он определен как private.

public staticили private staticпеременные часто используются для констант. Например, многие люди не любят «жестко кодировать» константы в своем коде; им нравится создавать переменную public staticили private staticсо значимым именем и использовать это в своем коде, что должно сделать код более читабельным. (Вы также должны сделать такие константы final).

Например:

public class Example {
    private final static String JDBC_URL = "jdbc:mysql://localhost/shopdb";
    private final static String JDBC_USERNAME = "username";
    private final static String JDBC_PASSWORD = "password";

    public static void main(String[] args) {
        Connection conn = DriverManager.getConnection(JDBC_URL,
                                         JDBC_USERNAME, JDBC_PASSWORD);

        // ...
    }
}

Делаете ли вы это publicили privateзависит от того, хотите ли вы, чтобы переменные были видны вне класса или нет.

Jesper
источник
6
Что необходимо для доступа как ClassName.var_nam? Где я могу получить к нему доступ напрямую: var_namв классе
Вайбхав Яни
12
Нет необходимости обращаться к нему через имя класса, но некоторые люди думают, что это хороший стиль, чтобы отличить его от нестатической переменной.
Джеспер
5
Что необходимо для доступа к нему с помощью статической переменной, мы можем написать "private final String JDBC_PASSWORD =" password ";" вместо использования статической переменной для этой строки пароля.
Чайтанья
48
@chaitanya Это константа. Почему вы хотите иметь копию переменной для каждого экземпляра класса, сделав ее нестатической?
Джеспер
16
static является переменной уровня класса, которая является общей, и существует только одна копия для всех экземпляров этого класса. Правило применимо, является ли оно частным или публичным. private просто говорит, что я не хочу, чтобы сторонний мир искажал значение моей переменной (для не финальной статики). Если статический элемент является окончательным, то сделать его публичным не повредит, так как никто не может изменить его значение.
user1923551
94

Статические переменные имеют одно значение для всех экземпляров класса.

Если бы вы должны были сделать что-то вроде:

public class Person
{
    private static int numberOfEyes;
    private String name;
}

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

TofuBeer
источник
3
Это не относится к закрытым статическим переменным, если только вы не пишете методы доступа для закрытой переменной, поскольку к ним нельзя получить доступ извне класса.
Ганеш Кришнан
2
Неверно @GaneshKrishnan, любой экземпляр класса имеет доступ к обеим переменным. Естественно, вы можете ожидать, что автор класса не сделает глупости. Также с рефлексией и JNI все ставки сняты.
TofuBeer
46

Закрытые статические переменные полезны так же, как и закрытые переменные экземпляра: они хранят состояние, к которому обращается только код в том же классе. Доступность (private / public / etc) и экземпляр / статический характер переменной являются полностью ортогональными понятиями.

Я бы не думал, что статические переменные являются общими для всех экземпляров класса, что предполагает наличие хотя бы одного экземпляра для состояния. Нет - статическая переменная связана с самим типом , а не каких - либо экземпляров типа.

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

Кроме того, я настоятельно рекомендую, чтобы единственным типом переменных, которые вы делаете общедоступными (или даже не частными), были константы - статические конечные переменные неизменяемых типов. Все остальное должно быть приватным, чтобы разделить API и реализацию (среди прочего).

Джон Скит
источник
Можете ли вы объяснить немного больше о разнице между доступом к частным статическим и частным не статическим переменным в одном классе?
Дхармендра
1
@Dharmendra: Мне не понятно, что вы имеете в виду. Приватная часть не имеет значения - что именно вас смущает в разнице между статическими переменными и переменными экземпляра?
Джон Скит
Какая разница в доступности, когда мы используем статические и нестатические переменные внутри одного класса, где они объявлены?
Дхармендра
2
@YogGuru: я не вижу актуальности вопроса. Сделайте его приватным, если хотите, чтобы он был приватным, и статическим, если хотите, чтобы он был статическим. Они ортогональны.
Джон Скит
1
@ryvantage: нет, совсем нет. Статический метод может получить к нему доступ без проблем.
Джон Скит
11

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

Вот пример:

Class test {
   public static String name = "AA";
   private static String age;

   public static void setAge(String yourAge) {
       //here if the age variable is not static you will get an error that you cannot access non static variables from static procedures so you have to make it static and private to not be accessed from other classes
       age = yourAge;
   }
}
Фарид Фархат
источник
3
Я думаю, что мне нравится этот ответ больше всего. +1. Единственный раз, когда имеет смысл использовать static в закрытой переменной, это если статический метод должен был получить к ней доступ.
Мукус,
Если вы не дадите классу правильное имя, вы не сможете сказать, является ли это допустимым вариантом использования. Например, если класс был вызван Person, то это, вероятно, было бы ошибкой, потому что у вас не могло быть нескольких людей разного возраста (если это был предполагаемый вариант использования).
DanMan
Я согласен @ Мукус. Это может быть единственным реальным ответом на этот вопрос. Я думаю, что OP уже понимает статичность, но люди, кажется, хотят объяснить это снова. Он спрашивает о конкретном сценарии. Возможность доступа к переменным в статических методах - это функциональность, которую добавляет «приватная статика». Я просто хочу также добавить, что он также позволяет вложенным статическим классам получать доступ к переменным.
Пинкертон
1
Как насчет памяти? При использовании static вам нужно будет создать только одну копию для класса, а не копию для каждого экземпляра. И очевидно, что с константой вам понадобится всего одна копия для класса. Сохраняет ли это память?
Пинкертон,
1
Я посмотрел это. Ответ на мой предыдущий вопрос: да, это экономит память
Пинкертон,
8

Ну, private staticпеременные могут быть использованы для обмена данными между экземплярами этого класса. Хотя вы правы, мы не можем получить доступ к private staticпеременным, используя конструкции типа ClassName.memberили, ClassInstance.memberно член всегда будет виден из методов этого класса или экземпляров этого класса. Таким образом, экземпляры этого класса всегда могут ссылаться на член.

Сваранга Сарма
источник
6

Какая польза от закрытой статической переменной класса?

Допустим, у вас есть книга из библиотеки Class. Каждый раз, когда вы создаете новую книгу, вы хотите присвоить ей уникальный идентификатор. Один из способов - просто начать с 0 и увеличить номер идентификатора. Но как все другие книги узнают последний созданный номер? Просто сохраните его как статическую переменную. Должны ли посетители знать, что действительный внутренний идентификационный номер предназначен для каждой книги? Нет. Эта информация является частной.

public class Book {
    private static int numBooks = 0;
    private int id;
    public String name;

    Book(String name) {
        id = numBooks++;
        this.name = name;
    }
}

Это надуманный пример, но я уверен, что вы легко можете вспомнить случаи, когда вы хотите, чтобы все экземпляры классов имели доступ к общей информации, которая должна быть конфиденциальной для всех остальных. Или даже если вы не можете, это хорошая практика программирования, чтобы сделать вещи как можно более частными. Что если вы случайно обнародовали это поле numBooks, хотя пользователи Book не должны были ничего с этим делать. Тогда кто-то может изменить количество Книг, не создавая новую Книгу.

Очень подлый!

iheanyi
источник
6

Объявление переменной private static varName;отличается от объявления переменной private varName;?

Да, оба разные. И первый вызывается, class variableпотому что он содержит одно значение для этого, classтогда как другой вызывается, instance variableпотому что он может содержать разные значения для разных instances(Objects). Первый создается только один раз в jvm, а другой создается один раз для каждого экземпляра, т. Е. Если у вас есть 10 экземпляров, то у вас будет 10 разных private varName;в jvm.

Объявляет ли переменная так же, как staticи другие специальные свойства?

Да, статические переменные получают некоторые свойства, отличные от обычных переменных экземпляра. Я уже упомянул немного, и давайте посмотрим некоторые здесь: class variables(переменные экземпляра, которые объявлены как статические) могут быть доступны напрямую с помощью имени класса, как ClassName.varName. И любой объект этого класса может получить доступ и изменить его значение в отличие от переменных экземпляра, доступных только его соответствующим объектам. Переменные класса могут использоваться в статических методах.

Какая польза от private static variableJava?

Логически, private static variableничем не отличается от public static variableпервого, который дает вам больше контроля. ИМО, вы можете буквально заменить public static variableна private static variableс помощьюpublic static методов получения и установки.

Одной из широко используемых областей private static variableявляется реализация простого Singletonшаблона, в котором у вас будет только один экземпляр этого класса во всем мире. Здесь staticидентификатор играет решающую роль, чтобы сделать этот единственный экземпляр доступным для внешнего мира (конечно, публичный статический метод получения также играет основную роль).

public class Singleton {
    private static Singleton singletonInstance = new Singleton();

    private Singleton(){}

    public static Singleton getInstance(){
        return Singleton.singletonInstance;
    }
}
АРН
источник
4

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

Raam
источник
3

Другая перспектива:

  1. Класс и его экземпляр - это две разные вещи во время выполнения. Информация о классе является «общей» для всех экземпляров этого класса.
  2. Нестатические переменные класса принадлежат экземплярам, ​​а статическая переменная принадлежит классу.
  3. Так же, как переменные экземпляра могут быть частными или общедоступными, статические переменные также могут быть частными или общедоступными.
Сантош
источник
1

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

private static int a=0;  
public static void testMethod() {  
        a=1;  
}
Neifen
источник
3
Хорошо, если ваш метод не имеет ссылки на экземпляр класса, конечно.
Джон Скит
1

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

Нагеш Трипати
источник
1

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

Вы должны посмотреть на мои примеры, если это не имеет смысла ниже. Зайдите сюда http://www.siteconsortium.com/h/D0000D.php

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

Вот и все.

    открытый класс SingletonExample {
      частный статический экземпляр SingletonExample = null;
      значение private static int = 0;
      private SingletonExample () {
        ++ this.value;
      }
      public static SingletonExample getInstance () {
        если (экземпляр! = NULL)
        вернуть экземпляр;
        synchronized (SingletonExample.class) {
        instance = new SingletonExample ();
        вернуть экземпляр;
        }
      }
      public void printValue () {
        System.out.print (this.value);
      }

      public static void main (String [] args) {
        SingletonExample instance = getInstance ();
        instance.printValue ();
        instance = getInstance ();
        instance.printValue ();
         }
    }

JTHouseCat
источник
1

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

Erdal76t
источник
0

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

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

Очень хорошим примером этого является sleep()метод в классе Thread

Thread.sleep(2500);

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

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

Другой распространенный пример

private static int numberOfCars=10;

public static int returnNumber(){

return numberOfCars;

}
ron_ron
источник
0

Я новичок в Java, но один из способов использования статических переменных, как полагают многие, - это подсчет числа экземпляров класса. например:

public Class Company {
    private static int numCompanies;

    public static int getNumCompanies(){
        return numCompanies;
    }
}

Тогда вы можете sysout:

Company.getNumCompanies();

Вы также можете получить доступ к numCompanies из каждого экземпляра класса (что я не совсем понимаю), но это не будет «статическим способом». Я понятия не имею, если это лучшая практика или нет, но это имеет смысл для меня.

pyetti
источник
0

*) Если переменная объявлена ​​как приватная, то она не видна за пределами класса. Это называется скрытием данных.

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

classname.variablename;

Дипак Бала
источник
0

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

public class PrivateStatic {

private static int var = 10;
public void setVar(int newVal) {
    var = newVal;
}

public int getVar() {
    return var;
}

public static void main(String... args) {
    PrivateStatic p1 = new Sub1();
    System.out.println(PrivateStatic.var);
    p1.setVar(200);

    PrivateStatic p2 = new Sub2();
    System.out.println(p2.getVar());
}
}


class Sub1 extends PrivateStatic {

}

class Sub2 extends PrivateStatic {
}
djiao
источник
0

ThreadLocalпеременные обычно реализуются как private static. Таким образом, они не привязаны к классу, и каждый поток имеет свою собственную ссылку на свой собственный объект ThreadLocal.

Мехмет Эрдемсой
источник
3
Я не понимаю этот ответ. Что вы имеете в виду?
H.Rabiee
-1

В следующем примере eyeизменяется PersonB, но legостается неизменным. Это связано с тем, что закрытая переменная делает копию себя для метода, поэтому ее первоначальное значение остается прежним; в то время как приватное статическое значение имеет только одну копию для всех методов, которыми нужно делиться, поэтому редактирование его значения изменит его первоначальное значение.

public class test {
private static int eye=2;
private int leg=3;

public test (int eyes, int legs){
    eye = eyes;
    leg=leg;
}

public test (){
}

public void print(){
    System.out.println(eye);
    System.out.println(leg);
}

public static void main(String[] args){
    test PersonA = new test();      
    test PersonB = new test(14,8);
    PersonA.print();    
}

}

> 14 3

Ицинь Дай
источник