2015-01-16 2 views
0

Учитывая два .java файлы:Java класс конкретизация осветление

// Car.java 
class Car { 
    static int counter = 0; // Class field 
    Car() { counter++;} 
} 

и

// Cars.java 
public class Cars{ 
    public static void main(String[] args){ 
     System.out.println(Car.counter); // Does this instantiate a Car? 
    } 
} 

Я учусь Java, и я просто пытаюсь быть точным (педантичный?) Здесь.

Компиляция, затем выполнение java Cars дает правильное значение 0. Поскольку автомобиль не был создан (или имеет его?), Что бы вы сказали в этом коде? Я имею в виду, я вижу, что Cars.class использует Car.class, но я не могу составить правильное предложение, чтобы описать, почему это сработало. Как бы вы описали эту концепцию создания класса «оживление» как бы начинающего?

+0

Возможно, я должен уточнить свой вопрос. Хорошо, поэтому я понимаю, что объект Car не будет создан. И я также понимаю разницу между полем класса и полем экземпляра. Что я не понимаю, так это то, что, поскольку объект не был создан, как появился автомобиль «вернуть» значение «0»? Возможно, я просто слишком много думаю об этом. – Sanuglia

+0

'counter' - переменная * класса *. Вам не нужен объект для доступа к переменной * класса *. – pbaldauf

ответ

1

Я предполагаю, что у вас есть два файла Car.java & Cars.java, соответствующий ваш данный код. Теперь, когда вы компилируете Cars.java, он автоматически также создаст Car.class вместе с Cars.class На самом деле этот Car.class необходим для запуска программы Cars.class. Если вы удалите прежний, а затем попробуйте запустить программу Автомобили, вы получите следующее исключение:

Exception in thread "main" java.lang.NoClassDefFoundError: Car 
     at Cars.main(Cars.java:3) 
Caused by: java.lang.ClassNotFoundException: Car 
     at java.net.URLClassLoader$1.run(Unknown Source) 
     at java.net.URLClassLoader$1.run(Unknown Source) 
     at java.security.AccessController.doPrivileged(Native Method) 
     at java.net.URLClassLoader.findClass(Unknown Source) 
     at java.lang.ClassLoader.loadClass(Unknown Source) 
     at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) 
     at java.lang.ClassLoader.loadClass(Unknown Source) 
     ... 1 more 

Обратите внимание на источник исключения здесь

java.lang.ClassLoader.loadClass 

Java-Загрузчик классов является частью JRE, которая динамически загружает классы Java в JVM. Когда класс инициализируется, все экземпляры статической переменной помещаются в кучу. Так как ваша программа Cars.class ссылается на статическую переменную программы Car.class, она также загружает ее в JVM.

Обратите внимание, что загрузка сильно отличается от экземпляра. Фраза «создание экземпляра класса» означает создание «экземпляра» класса. Чтобы создать экземпляр класса, мы используем новый оператор, как:

Car myCar = new Car(); 

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

Таким образом, в вашей программе, вы не инстанцировании класс автомобилей, но вы все еще загрузки его в JVM.

+0

BINGO !! Это объяснение подтверждает мое понимание. СПАСИБО!! – Sanuglia

3

Нет, это не так. Car.counter используется для получения ссылки на counter в Car.

Ключевое слово static означает, что поле counter - это то, что принадлежит всему классу, а не отдельные экземпляры объекта. Поле counter поэтому имеет то же значение для всех экземпляров Car.

+1

Стоит упомянуть о 'static' модификаторе :) –

+1

@JorgeCampos, спасибо за подсказку, я разработал немного больше на нем;) –

+0

Это очень хороший ответ, хотя и не в центре моего вопроса. Спасибо Niels! – Sanuglia

0

Вы увеличиваете счетчик в конвоире автомобиля. Это означает, что счетчик увеличивается только тогда, когда вы создаете новый экземпляр автомобиля с использованием «нового автомобиля». Код не создает экземпляр любого автомобиля, который является путем счетчика 0.

1

Из Oracle Docs:

Иногда вы хотите иметь переменные, которые являются общими для всех объектов. Это достигается с помощью модификатора static. Поля, которые имеют модификатор static в своем объявлении, называются статические поля или переменные класса. Они связаны с классом, а не с каким-либо объектом. Каждый экземпляр класса использует переменную класса, которая находится в одном фиксированном месте в памяти. Любой объект может изменить значение переменной класса, но переменные класса также можно манипулировать, не создавая экземпляр класса.

Итак, чтобы ответить на ваш вопрос. НЕТ - при доступе к статическому полю вы делаете не экземпляр класса. Способ, которым вы фактически создаете объект, - это вызвать его constructor. Конструкторы вызываются с помощью ключевого слова new, а имя конструктора совпадает с именем класса.

Car c = new Car(); // instantiation via constructor 

Для того, чтобы описать свой случай:

Cars класс использует переменная класса из Car класса. Переменные класса: связаны с классом класса и разделяются между каждым экземпляром класса.

0

Просто сказал:

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

Но сами описания также можно рассматривать как объекты, которые следуют правилам описания. Эти объекты являются экземплярами класса Class - описание описания описания ;-):

System.out.println(Car.class instanceof Class); // true 
System.out.println(Class.class instanceof Class); // true 

Таким образом, вы можете видеть классы имеют представление (например, Car.class) и представления могут иметь поля и методы - самые static из них.

Просто сказал ;-)

0

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

Смежные вопросы