this
和super
关键字不是它们;那么我如何使用它们以与方法相同的方式将参数传递给构造函数?
简而言之,两者都能表现出如此明显的行为?
答案 0 :(得分:8)
您认为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的特殊表单仅在实例方法,实例初始值设定项或构造函数中有效,或在类的实例变量的初始值设定项中有效;这些与使用关键字的情况完全相同(§15.8.3)。
答案 1 :(得分:3)
Java语言为这两个关键字提供了特定的处理方式,并且在有限的上下文中允许使用它们。
调用this(...)将导致字节码将调用当前类的相应构造函数,而调用super(...)将导致字节码将调用超类型上的相应构造函数。
Java为这些提供了特殊处理,因为它们的绑定与普通方法的绑定不同(即,您希望避免动态调用,或者您永远无法在超类型上获取构造函数)。
每种语言都必须处理这个问题。例如,在C ++中,您显式指定父方法的名称而不是使用super。
答案 2 :(得分:1)
我不完全确定你在这里问的是什么,但这是语言设计的方式。编译器知道在构造函数中执行此操作时:
super("I'm a string!", 32);
它应该在超类中找到一个构造函数,它接受一个String和一个int作为参数。
答案 3 :(得分:1)
您可以从子类中传递提供给父级的变量。示例比长解释更好,所以这里是为您自己的用法扩展异常类的一个非常通用的示例:
public class MyException extends Exception {
public MyException()
{
}
public MyException(String message)
{
super(message);
}
public MyException(String string, Throwable e)
{
super(string, e);
}
}
答案 4 :(得分:0)
这些如何能够表现出来 不同的行为
这个问题没有意义。 所有关键字都有不同的行为。这就是他们的目的。
答案 5 :(得分:0)
我不确定这里有什么疑问。此this
引用了对当前实例的引用,也称为this(arg)
,当它调用当前constructor
中的相应class
时。同样,当调用super()
时,它会调用constructor
类中的相应super
。它们只能从constructor
调用。
答案 6 :(得分:-1)
根据Wikipedia,this
和super
是关键字,我想这就是他们如何摆脱所有魔法。