【问题标题】:this and super in javajava中的this和super
【发布时间】:2023-03-10 10:28:01
【问题描述】:

this 和 super 是关键字,不是吗?那么我如何使用它们将参数传递给构造函数,就像使用方法一样? 简而言之,两者如何表现出如此不同的行为??

【问题讨论】:

    标签: java


    【解决方案1】:

    this 和 super 都是关键字是正确的。 Java language specification 明确定义了它们的行为方式。简短的回答是,这些关键字的行为特殊,因为规范规定它们必须这样做。

    根据规范this 可以使用primary expression(仅在某些地方)或explicit constructor invocation。

    关键字 this 只能用在实例方法体、实例初始化器或构造器中,或者用在类的实例变量的初始化器中。如果它出现在其他任何地方,则会发生编译时错误。

    因此您可以使用this 作为函数的参数来传递对当前对象的引用。但是请注意,您不能以同样的方式使用 super,因为它不是主要表达式:

    public class Program
    {   
        void test(Program p) {}
    
        void run() { test(super); }
    
        public static void main(String[] args)
        {
            new Program().run();
        }
    }
    

    结果:

    Program.java:5: '.' expected
        void run() { test(super); }
    

    您可以使用super.foo,因为这是在15.11 中定义的有效:

    FieldAccess:
        Primary . Identifier
        super . Identifier
        ClassName .super . Identifier
    

    规范中还放了restrictions on how super can be used:

    使用关键字super的特殊形式只在实例方法、实例初始化器或构造器中有效,或者在类的实例变量的初始化器中有效;这些与可以使用关键字 this 的情况完全相同(第 15.8.3 节)。

    【讨论】:

    • +1 表示将其作为参数传递,同样不适用于 super
    【解决方案2】:

    Java 语言为这两个关键字提供了特定的处理方式,并且允许在有限的上下文中使用它们。

    调用 this(...) 将导致调用当前类上相应构造函数的字节码,而调用 super(...) 将导致调用超类型上相应构造函数的字节码。

    Java 为这些提供了特殊处理,因为它们的绑定不同于普通方法的绑定(即,您希望避免动态调用,否则您将永远无法获得超类型上的构造函数)。

    每种语言都必须处理这个问题。例如,在 C++ 中,您显式指定父方法的名称,而不是使用 super。

    【讨论】:

    • 对于这种行为,在 super 和 this 下是否有任何编码?
    • @abson 它是由你编码的,但不是你的。我想它是 JVM 的一部分,或者可能是编译器。你应该把 this 和 super 看作 + 和 - 一样,编译器只知道如何处理它们。
    【解决方案3】:

    我不完全确定您在这里问的是什么,但这就是语言的设计方式。编译器知道,当您在构造函数中执行此操作时:

    super("I'm a string!", 32);
    

    它应该在超类中找到一个以 String 和 int 作为参数的构造函数。

    【讨论】:

      【解决方案4】:

      从您的子类中,您可以将提供的变量传递给您的父类。示例比冗长的解释更好,所以这里有一个非常通用的扩展异常类的示例供您自己使用:

      public class MyException extends Exception {    
      public MyException()
      {
      
      }
      
      public MyException(String message)
      {
          super(message);
      }
      
      public MyException(String string, Throwable e) 
      {
          super(string, e);
      } 
      } 
      

      【讨论】:

        【解决方案5】:

        这些怎么能显示出这样的 不同的行为

        这个问题没有意义。 所有关键字具有不同的行为。这就是他们的目的。

        【讨论】:

          【解决方案6】:

          我不确定这里有什么疑问。这个this 指的是对当前实例的引用,当像this(arg) 这样调用时,它也会调用当前class 中对应的constructor。同样,当super() 被调用时,它会调用super 类中对应的constructor。只能从constructor 调用它们。

          【讨论】:

            【解决方案7】:

            根据Wikipedia,this 和super 是关键字,我想这就是他们摆脱所有魔法的方式。

            【讨论】:

            • 根据JLS,它们是关键字。维基百科不是规范性参考。
            猜你喜欢
            • 1970-01-01
            • 2011-04-30
            • 1970-01-01
            • 1970-01-01
            • 2016-10-29
            • 2013-11-17
            • 1970-01-01
            • 2011-04-15
            • 2014-03-27
            相关资源
            最近更新 更多