【发布时间】:2023-03-10 10:28:01
【问题描述】:
this 和 super 是关键字,不是吗?那么我如何使用它们将参数传递给构造函数,就像使用方法一样?
简而言之,两者如何表现出如此不同的行为??
【问题讨论】:
标签: java
this 和 super 是关键字,不是吗?那么我如何使用它们将参数传递给构造函数,就像使用方法一样?
简而言之,两者如何表现出如此不同的行为??
【问题讨论】:
标签: java
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 节)。
【讨论】:
Java 语言为这两个关键字提供了特定的处理方式,并且允许在有限的上下文中使用它们。
调用 this(...) 将导致调用当前类上相应构造函数的字节码,而调用 super(...) 将导致调用超类型上相应构造函数的字节码。
Java 为这些提供了特殊处理,因为它们的绑定不同于普通方法的绑定(即,您希望避免动态调用,否则您将永远无法获得超类型上的构造函数)。
每种语言都必须处理这个问题。例如,在 C++ 中,您显式指定父方法的名称,而不是使用 super。
【讨论】:
我不完全确定您在这里问的是什么,但这就是语言的设计方式。编译器知道,当您在构造函数中执行此操作时:
super("I'm a string!", 32);
它应该在超类中找到一个以 String 和 int 作为参数的构造函数。
【讨论】:
从您的子类中,您可以将提供的变量传递给您的父类。示例比冗长的解释更好,所以这里有一个非常通用的扩展异常类的示例供您自己使用:
public class MyException extends Exception {
public MyException()
{
}
public MyException(String message)
{
super(message);
}
public MyException(String string, Throwable e)
{
super(string, e);
}
}
【讨论】:
这些怎么能显示出这样的 不同的行为
这个问题没有意义。 所有关键字具有不同的行为。这就是他们的目的。
【讨论】:
我不确定这里有什么疑问。这个this 指的是对当前实例的引用,当像this(arg) 这样调用时,它也会调用当前class 中对应的constructor。同样,当super() 被调用时,它会调用super 类中对应的constructor。只能从constructor 调用它们。
【讨论】: