У чому полягає використання приватної статичної змінної на 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залежить від того, хочете, щоб змінні були видні поза класом чи ні.


6
Що потрібно для доступу ClassName.var_nam? Де я можу отримати доступ до нього безпосередньо: var_namв межах класу
Vaibhav Jani

12
До нього не потрібно звертатися через назву класу, але деякі люди вважають, що це гарний стиль, щоб відрізняти його від нестатичної змінної.
Jesper

5
що потрібно для доступу до нього за допомогою статичної змінної, ми можемо написати "приватний заключний рядок JDBC_PASSWORD =" пароль ";" замість використання статичної змінної для цього рядка пароля.
чайтанья

48
@chaitanya Це постійна. Чому ви хочете мати копію змінної для кожного примірника класу, зробивши її нестатичною?
Jesper

16
static є змінною рівня класу, яка є загальною, і існує лише одна копія для всіх примірників цього класу. Правило застосовне, незалежно від того, приватне воно чи державне. приватний просто каже, що я не хочу, щоб зовнішній світ псував моє змінне значення (для не остаточної статики). Якщо статика остаточна, то немає ніякої шкоди зробити її загальнодоступною, оскільки ніхто не може змінити її значення.
користувач1923551

94

Статичні змінні мають єдине значення для всіх примірників класу.

Якби ви робили щось на кшталт:

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

і тоді ви хотіли змінити своє ім’я, це добре, моє ім’я залишається таким же. Якби ви хотіли змінити це так, щоб у вас було 17 очей, то всі у світі також мали б 17 очей.


3
Це не застосовується до приватних статичних змінних, якщо ви також не записуєте методи accessor для приватної змінної, оскільки вони не можуть бути доступні за межами класу.
Ганеш Крішнан

2
Неправда @GaneshKrishnan, будь-який примірник класу має доступ до обох змінних. Природно, можна очікувати, що автор класу не зробить щось дурне. Крім того, за умови роздумів та JNI всі ставки відключені.
TofuBeer

46

Приватні статичні змінні корисні так само, як корисні приватні змінні екземпляри: вони зберігають стан, доступ до якого здійснюється лише за допомогою коду в межах одного класу. Доступність (приватна / публічна / тощо) та екземпляр / статична природа змінної є повністю ортогональними поняттями.

Я б уникав думати про статичні змінні як про спільний розподіл між "усіма екземплярами" класу - це дозволяє припустити, що для стану присутності хоча б один екземпляр. Ні - статична змінна пов'язана з самим типом замість будь-яких екземплярів типу.

Тому будь-коли, коли ви хочете, щоб якийсь стан, який асоціювався з типом, а не будь-яким конкретним екземпляром, і вам потрібно було зберегти цей стан приватним (можливо, дозволяючи, наприклад, керований доступ через властивості), має сенс мати приватну статичну змінну.

На відміну від цього, я настійно рекомендую, щоб єдиним типом змінних, які ви оприлюднюєте (або навіть не приватними), є константи - статичні кінцеві змінні змінних типів. Все інше повинно бути приватним задля відокремлення 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

Я згоден @Mukus. Це може бути єдиною реальною відповіддю на це питання. Я думаю, що ОП вже розуміє статичне, але, здається, люди хочуть пояснити це ще раз. Він запитує про конкретний сценарій. Можливість доступу до змінних у статичних методах - це функціонал, який додає "приватний статичний". Я просто хочу також додати, що це дозволяє вкладеним статичним КЛАСАМ доступ до змінних.
Пінкертон

1
А що з пам’яттю? За допомогою статики ви створюєте лише одну копію для класу, а не копію для кожного примірника. І очевидно, що при постійній роботі вам знадобиться лише один примірник для класу. Це економить пам’ять?
Пінкертон

1
Я подивився. Відповідь на моє попереднє запитання: так, це економить пам’ять
Pinkerton

8

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


6

У чому полягає використання приватної змінної статичного класу?

Скажімо, у вас є бібліотечний клас книги. Кожен раз, коли ви створюєте нову Книгу, ви хочете призначити їй унікальний ідентифікатор. Один із способів - просто почати з 0 і збільшити номер id. Але, як усі інші книги знають останній створений ідентифікаційний номер? Просто, збережіть його як статичну змінну. Чи повинні меценати знати, що власне внутрішній номер ідентифікатора є для кожної книги? Ні. Ця інформація є приватною.

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

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

Це надуманий приклад, але я впевнений, що ви можете легко придумати випадки, коли ви хочете, щоб усі екземпляри класу мали доступ до загальної інформації, яку слід зберігати приватною для всіх інших. Або навіть якщо ви не можете, це корисна практика програмування, щоб зробити речі максимально приватними. Що робити, якщо ви випадково зробили це поле «публічні книги» загальнодоступним, навіть якщо користувачі Книги з цим не мали нічого робити. Тоді хтось міг змінити кількість Книг без створення нової Книги.

Дуже підлий!


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 variableв Java?

За логікою, private static variableвін нічим не відрізняється від public static variableпершого, який дає вам більше контролю. IMO, ви можете буквально замінити 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

Приватне ключове слово буде використовуватися для змінного доступу в класі та зберігання статичного в тому сенсі, що ми можемо отримати доступ до змінної в статичному методі, але також до змінної не можна отримати доступ у статичному методі.


3

Інша перспектива:

  1. Клас та його екземпляр - це дві різні речі під час виконання. Інформація про клас "надається" всіма примірниками цього класу.
  2. Нестатичні змінні класу належать до примірників, а статична змінна належить до класу.
  3. Так само, як змінні екземпляра можуть бути приватними або загальнодоступними, статичні змінні також можуть бути приватними або загальнодоступними.

1

Коли в статичному методі ви використовуєте змінну, змінна повинна бути статичною також як приклад:

private static int a=0;  
public static void testMethod() {  
        a=1;  
}

3
Ну, якщо тільки ваш метод не посилається на екземпляр класу курсу.
Джон Скіт

1

Статичні змінні - це ті змінні, які є загальними для всіх екземплярів класу. Якщо один екземпляр змінить його .. тоді значення статичної змінної буде оновлено для всіх інших примірників


1

Для деяких людей це має більше сенсу, якщо вони бачать це на декількох різних мовах, тому я написав приклад на Java та PHP на своїй сторінці, де пояснюю деякі з цих модифікаторів. Ви можете думати про це неправильно.

Ви повинні подивитися на мої приклади, якщо це не має сенсу нижче. Перейдіть сюди http://www.siteconsortium.com/h/D0000D.php

Суть хоч полягає в тому, що це майже все саме те, що він говорить. Це статична змінна члена, яка є приватною. Наприклад, якщо ви хотіли створити об'єкт Singleton, чому ви хочете зробити змінну SingletonExample.instance загальнодоступною. Якщо ви зробили людину, яка використовувала клас, ви могли легко перезаписати значення.

Ось і все.

    публічний клас SingletonExample {
      приватний статичний екземпляр SingletonExample = null;
      приватне статичне значення int = 0;
      приватний SingletonExample () {
        ++ це.значення;
      }
      загальнодоступний статичний SingletonExample getInstance () {
        if (екземпляр! = null)
        повернути екземпляр;
        синхронізований (SingletonExample.class) {
        instance = новий SingletonExample ();
        повернути екземпляр;
        }
      }
      public void printValue () {
        System.out.print (це значення);
      }

      public static void main (String [] args) {
        Екземпляр SingletonExample = getInstance ();
        instance.printValue ();
        instance = getInstance ();
        instance.printValue ();
         }
    }


1

Якщо ви використовуєте приватні статичні змінні у своєму класі, статичні внутрішні класи у вашому класі можуть охопити ваші змінні. Це абсолютно добре для безпеки контексту.


0

Якщо змінна визначена як публічна статична, до неї можна отримати доступ через її ім'я з будь-якого класу.

Зазвичай функції визначаються як загальнодоступна статика, доступ до якої можна отримати лише за допомогою виклику імені класу реалізації.

Дуже хорошим прикладом цього є sleep()метод у класі Thread

Thread.sleep(2500);

Якщо змінна визначена як приватна статична, до неї можна отримати доступ лише в межах цього класу, тому ім'я класу не потрібно або ви все одно можете використовувати ім'я класу (до вас). Різниця між приватним var_name і приватним статичним var_name полягає в тому, що до приватних статичних змінних можна отримати доступ лише статичними методами класу, тоді як до приватних змінних можна отримати доступ будь-яким методом цього класу (крім статичних методів)

Дуже хорошим прикладом цього є визначення підключень або констант бази даних, які потребують оголошення змінної як приватної статичної.

Ще один поширений приклад:

private static int numberOfCars=10;

public static int returnNumber(){

return numberOfCars;

}

0

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

public Class Company {
    private static int numCompanies;

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

Тоді ви можете систематизувати:

Company.getNumCompanies();

Ви також можете отримати доступ до numCompanies від кожного примірника класу (якого я не повністю розумію), але це не буде "статичним способом". Я поняття не маю, це найкраща практика чи ні, але це має сенс для мене.


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 {
}

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.