#java #class #variables #static
#java #класс #переменные #статический
Вопрос:
Я только начал изучать Java и написал класс для тестирования с использованием статических полей. Все работает нормально, но в Eclipse я вижу значок, который при наведении на который отображается как: «К статическому методу getCounter из типа CarCounter следует обращаться статическим способом«. Тогда каков правильный способ?
Вот класс:
public class CarCounter {
static int counter = 0;
public CarCounter(){
counter ;
}
public static int getCounter(){
return counter;
}
}
И здесь я пытаюсь получить доступ к счетчику переменных:
public class CarCounterTest {
public static void main( String args[] ){
CarCounter a = new CarCounter();
System.out.println(a.getCounter()); //This is where the icon is marked
}
}
Ответ №1:
Статические поля и методы принадлежат не конкретному объекту, а классу, поэтому вы должны обращаться к ним из класса, а не из объекта:
CarCounter.getCounter()
и не
a.getCounter()
Комментарии:
1. замените need на should , поскольку обе строки кода верны, но вторая не рекомендуется
2. Это ответило на этот вопрос за меня; ваш ответ был коротким и в то же время лаконичным. Удивительно!
3. @Binyamin Sharet Я знаю, что это был более старый вопрос, но ваш комментарий помог мне в моем проекте. Спасибо!
Ответ №2:
Используйте CarCounter.getCounter()
. Это дает понять, что это не имеет ничего общего с объектом, на который ссылается значение a
переменной — счетчик связан с самим типом, а не с каким-либо конкретным экземпляром типа.
Вот пример того, почему это действительно важно:
Thread t = new Thread(runnable);
t.start();
t.sleep(1000);
На что похоже, что делает этот код? Похоже, что он запускает новый поток, а затем каким-то образом «приостанавливает» его — переводит в спящий режим на секунду.
Фактически, это запуск нового потока и приостановка текущего потока, потому что Thread.sleep
это статический метод, который всегда переводит текущий поток в спящий режим. Это не может перевести любой другой поток в спящий режим. Это намного понятнее, когда это явно:
Thread t = new Thread(runnable);
t.start();
Thread.sleep(1000);
По сути, способность первого фрагмента кода компилироваться — это ошибка разработчиков языка 🙁
Комментарии:
1. разработчики c # исправили эту ошибку.
Ответ №3:
Это было бы:
System.out.println(CarCounter.getCounter());
Ответ №4:
Возможно даже, хотя и крайне не рекомендуется, написать:
Math m = null;
double d = m.sin(m.PI/4.0);
System.out.println("This should be close to 0.5 " (d*d));
Это потому, что статические обращения смотрят на объявленный тип переменной и фактически никогда не разыменовывают ее.
Ответ №5:
Статические элементы принадлежат классу. Следовательно, лучший способ получить к ним доступ — через класс. Итак, в вашем случае распечатка должна быть.
System.out.println(CarCounter.getCounter());
Это может показаться банально ненужным, но это не так.
Рассмотрим следующий код
// VehicleCounter.java
public class VehicleCounter {
static int counter = 0;
public VehicleCounter(){
counter ;
}
public static int getCounter(){
return counter;
}
}
// CarCounter.java
public class CarCounter extends VehicleCounter {
static int counter = 0;
public CarCounter(){
counter ;
}
public static int getCounter(){
return counter;
}
}
// CarCounterTest.java
public class CarCounterTest {
public static void main( String args[] ){
VehicleCounter vehicle1 = new VehicleCounter();
VehicleCounter vehicle2 = new CarCounter();
System.out.println(vehicle1.getCounter());
System.out.println(vehicle2.getCounter());
}
}
Что должен выводить приведенный выше код?
Поведение приведенного выше кода трудно определить. vehicle1
объявляется как VehicleCounter
, а объект на самом деле является VehicleCounter
, поэтому он должен напечатать 2 (создаются два транспортных средства).
vehicle2
объявлен как, VehicleCounter
но объект является фактическим CarCounter
. Что должно быть напечатано?
Я действительно не знаю, что будет напечатано, но я вижу, что это можно легко перепутать. Итак, для лучшей практики доступ к статическим элементам всегда должен осуществляться через класс, который он определил.
Гораздо проще предсказать, что будет напечатано с помощью следующего кода.
// CarCounterTest.java
public class CarCounterTest {
public static void main( String args[] ){
VehicleCounter vehicle1 = new VehicleCounter();
VehicleCounter vehicle2 = new CarCounter();
System.out.println(VehicleCounter.getCounter());
System.out.println(CarCounter .getCounter());
}
}
Надеюсь, это объясняет.
NawaMan 😀
Ответ №6:
Доступ к статическим элементам должен осуществляться статически, т.Е. className.MemberName. Нестатический доступ разрешен, хотя (имя_объекта.имя_участника), но не рекомендуется.