Если ключевое слово this не может использоваться внутри метода stati c, то как метод1 () вызывает метод2 () в данном коде? - PullRequest
0 голосов
/ 10 июля 2020
  public class Main {
  static void method1()
   {
       System.out.println("In method1");
       method2(); //Is this equivalent to this.method2()?
   }
   static void method2()
   {
       System.out.println("In method2");
   }
   public static void main(String args[]) {
       Main.method1();
   }
}

Закомментированная строка эквивалентна this.method2()? Потому что в случае экземпляра метод this автоматически добавляется компилятором, но я читал, что метод stati c не может ссылаться на this. Если this здесь не упоминается, как происходит вызов метода для method2()?

Ответы [ 4 ]

2 голосов
/ 10 июля 2020

A class - это набор объектов abstract-i sh, определяемый их ссылкой на объект, характеризуемый их атрибутами (которые являются членами данных) и их способностями (то есть их методами).

Давайте начнем с того, в чем вы правы: на экземпляр, то есть на объект, можно ссылаться внутри его методов через ключевое слово this. Что вы делаете не понимаете, так это то, что static означает class -уровень. Когда мы говорим о методах уровня class, нет экземпляра для ссылки, а this не имеет смысла.

В вашем примере вы вызываете метод уровня class внутри другого class -уровневый метод. Здесь нет this, ни явно, ни неявно.

Рассмотрим аналогию:

Давайте рассмотрим набор Bird. Экземпляр Bird может .fly(), весь класс Bird не может .fly(), потому что пока экземпляр Bird летает, другой сидит на своих яйцах. Однако у птиц могут быть коллективные действия, например .flyInFlock(). Один экземпляр Bird не может .flyInFlock(), но Bird, поскольку class может это сделать, потому что это class -уровень, на который ссылается ключевое слово stati c.

Методы уровня экземпляра могут быть вызваны через:

  • ссылку на объект, например bird.fly ()
  • через this внутри метода уровня экземпляра class , например, this.fly()
  • через его имя, с тем же условием, что и во втором случае здесь, как fly()

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

1 голос
/ 10 июля 2020

Использование ключевого слова this означает этот экземпляр класса Main. Используемая вами строка равна Main.method2(), а не this.method2(). Если бы вы использовали метод, отличный от c, он был бы равен this.method2(). Метод stati c принадлежит классу, а не экземпляру этого класса. Следовательно, на него нельзя ссылаться this, который является экземпляром класса.

1 голос
/ 10 июля 2020

Ключевое слово this всегда относится к текущему экземпляру класса, с которым вы «работаете прямо сейчас». Внутри метода stati c не может быть экземпляра объекта и, следовательно, не может быть this, потому что метод stati c по определению существует независимо от каких-либо экземпляров. Это также означает, что вы не можете вызывать какой-либо нестатический c метод вашего класса внутри метода stati c, потому что this просто недоступен.

Вы можете вызывать любой stati c метод из любого места, потому что они не зависят от экземпляров. Вот почему method1() может вызывать method2().

Кроме того, вы можете (но не обязаны) указать имя класса, как вы это делали при вызове Main.method1(). Удаление ведущего Main. приведет к тому же вызову, поскольку вы ссылаетесь на метод stati c в том же классе. То же самое касается звонка на method2(). Вместо этого вы можете добавить имя класса, чтобы вызов выглядел как Main.method2(), и это привело бы к тому же вызову.

Эта вещь с пространством имен начинает иметь смысл только при вызове методов stati c из разные классы, и вам нужно указать, о каком классе вы говорите.

0 голосов
/ 10 июля 2020

Оба метода - stati c.

  • вы не можете использовать this в методе stati c.
  • вы можете ссылаться на другие stati c методы

Давайте проверим сгенерированный байт-код

static method1()V
   L0
    LINENUMBER 6 L0
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    LDC "In method1"
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
   L1
    LINENUMBER 7 L1
    INVOKESTATIC mypackage/Main.method2 ()V
   L2
    LINENUMBER 8 L2
    RETURN
    MAXSTACK = 2
    MAXLOCALS = 0

Вы можете видеть, что INVOKESTATIC mypackage/Main.method2 ()V ссылается на имя класса и имя метода.

...