Java Статическая путаница - PullRequest
       1

Java Статическая путаница

3 голосов
/ 31 августа 2010

Я работаю с Java;Я работал с C ++ раньше.Я думаю о статическом использовании в Java.Если я создаю статические методы и переменные в классе, почему я могу получить к ним доступ также через объект?

Пример:

class Test{
  static int count=0;
  int id;
  static void updatec(){
    count++
   }
}

class TestMain
{
   public static void main(String args[])
   {
         Test.count=1;
         Test t = new Test();
         t.count=5; // Valid WHY ?????
   }
}

Почему это разрешено?Сайт Java говорит, что мы не должны использовать метод / переменную obj.static.
Почему это разрешено?

Ответы [ 7 ]

7 голосов
/ 31 августа 2010

Статика не означает, что поле предназначено только для класса. Это означает, что для класса и всех его экземпляров .

В этом примере на переменную класса origin класса Point ссылаются как с использованием имени класса в качестве квалификатора в Point.origin, так и с использованием переменных типа класса в выражениях доступа к полю ( §15.11 ) , как в p.origin и q.origin. Эти два способа доступа к переменной класса origin обращаются к одному и тому же объекту, о чем свидетельствует тот факт, что значение выражения равенства ссылок ( §15.21.3 ):
q.origin==Point.origin верно

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


Ресурсы:

3 голосов
/ 31 августа 2010

Доступ к статическим полям через экземпляр разрешен, хотя обычно вы получаете предупреждение об этом. Тем не менее, поле все еще статично, поэтому в каждом классе есть только одно:

     Test t = new Test();
     Test u = new Test();
     t.count = 5;
     System.out.println(u.count); // Outputs 5
2 голосов
/ 31 августа 2010

Это действительно не должно было поддерживаться.Эта поддержка приводит к сомнительному коду в org.apache.commons.cli синтаксическом анализаторе командной строки.

class OptionBuilder

public static Option create();
public static OptionBuilder withLongOpt(String newLongopt);
public static OptionBuilder withDescription(String newDescription);

Это приводит к следующему:

Option opt =
  OptionBuilder
    .withLongOpt( "opt" )
    .withDescription( "opt description" )
    .create( );

Это было бы намного лучше, чище и поточнее, если был конструктор OptionBuilder по умолчанию и все статические методы были методами экземпляра.Это модель, используемая StringBuilder / StringBuffer

2 голосов
/ 31 августа 2010

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

1 голос
/ 31 августа 2010

Ваш фрагмент вполне допустим, либо в Java, либо в эквиваленте C ++.

Кажется, вы путаете ограничение доступа (private, protected, public) и различие экземпляра / класса для членов (static ключевое слово).

Поскольку у вас есть экземпляр класса Test (с именем t) в статическом методе main, вы можете использовать методы экземпляра / члены класса Test, что соответствует документации, которую вы цитировали.

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

1 голос
/ 31 августа 2010

Вы не должны означать, что не можете.

В любом случае, это разрешено и в C ++.

0 голосов
/ 31 августа 2010

static в этом случае означает, что есть один общий экземпляр на класс, а не на экземпляр.Поэтому, когда вы изменяете t.count, вы изменяете член 'count' для всего класса и ВСЕХ экземпляров.

То есть они будут печатать одно и то же значение:

System.out.println(t.count);
System.out.println(Test.count);

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

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