关于Java静态方法的问题。
Animal()
{
this(makeRandomName());
}
我在Java中使用此代码,在创建动物对象时调用该代码:
Animal a = new Animal()
makeRandomName
是一种方法,它使用Math.random()
返回从String值数组中随机获取的String。
如果我没有将方法makeRandomName指定为 static ,我会收到此错误(可以解释原因):
线程中的异常" main" java.lang.RuntimeException:无法编译 源代码 - 在超类型构造函数之前不能引用它 被称为
此外,当Animal构造函数定义如下:
Animal()
{
this.name = makeRandomName();
}
我没有收到任何错误,无论是否makeRandomName是静态还是非静态。为什么?
有什么区别
this.name = makeRandomName();
和this(makeRandomName());
我之前从未见过这种语法this(method_name())
,我只见过this.instance_variable = value
,所以我有点困惑。我确信这与超级构造函数和调用方法的顺序有关,但是在这种情况下看到方法和构造函数的专家分析以及调用方法的顺序会很棒。非常感谢提前!
我被要求发布整个代码:
public class Animal {
String name;
Animal (String n)
{
this.name = n;
}
Animal()
{
this(makeRandomName());
//this.name=makeRandomName();
}
static String makeRandomName()
{
int x = (int) (Math.random()*5);
String l[] = new String[] {"Zlatan", "Ibra", "Edinson", "Gigi", "T"};
return l[x];
}
public static void main(String [] args)
{
Animal a = new Animal();
Animal b = new Animal("M");
System.out.println(a.name);
System.out.println(b.name);
}
}
答案 0 :(得分:8)
对于第一个问题 - 必须将makeRandomName()
指定为静态的原因是因为makeRandomName()
是一个实例方法,并且在构造函数中调用super
之后才能访问它,这导致类被初始化。您尝试做的是在调用makeRandomName()
之前调用super
初始化类,从而导致编译错误。
对于第二个问题 - 在super();
的声明之前隐含地呼叫this.name = makeRandomName();
。 super(...);
必须始终是构造函数中的第一个语句,即使您没有明确地编写它。因此,第二个构造函数的实际代码是:
Animal() {
super();
this.name = makeRandomName();
}
此时 makeRandomName()
是可访问的,即使它被声明为非静态因为已经构造了对象。
答案 1 :(得分:1)
在第一种情况this()
中,您尝试调用类构造函数,并尝试将该类中定义的方法的结果传递给它。您首先创建的对象此时尚未初始化,因此它尝试从尚未初始化的内部访问方法。必须先调用super()
才能访问该方法,但在这种情况下,您无法调用super()
然后this()
,因为java要求this()
成为您的第一个语句构造函数,如果你把它放在那里。
this(makeRandomName())
正在调用构造函数并尝试将makeRandomName()
的结果传递给构造函数调用。问题是该对象此时尚未初始化,因此无法调用makeRandomName()
。
this.name = makeRandomName()
在初始化对象后将makeRandomName()
的返回值分配给类的实例变量
在构造函数中调用构造函数是没有意义的,因为你会发生递归情况......除非有一些设计理由这样做但在这种情况下你需要一个基本案例来突破在某些时候递归。
答案 2 :(得分:1)
您正在看到此问题,因为您正在调用对象(vs Class)方法:" makeRandomName"在运行超类构造函数之前(您将结果作为参数传递)。在对象上运行任何方法之前,对象的超级构造函数必须已执行。这就是为什么它始终是构造函数的第一行
答案 3 :(得分:1)
您在instance method
之前调用了super()
makeRandomName(),因为尚未创建实例/对象,因此无法访问它。
以下构造函数的工作原理是构造函数本身默认在构造函数体的super()
中调用first line
。
Animal() {
//this(makeRandomName());
this.name=makeRandomName();
}
您调用this()
的以下构造函数,在这种情况下super()
将不会在构造函数Animal()
中调用,但在Animal(String name)
中,不幸的是makeRandomName()
不是Animal() {
this(makeRandomName());
//this.name=makeRandomName();
}
Animal(String name){
// super() is invoked implicitly here...
}
访问。
Dim processedRow As Integer
Dim rngVlookupData As Range
Dim ws As Worksheet
... code ...
Set ws = ThisWorkbook.Sheets("HR Eval Report")
ws.Range("BC8", "BBD8").Select
ws.Range(Selection, Selection.End(xlDown)).Select
Set rngVlookupData = Selection
Range(Cells(processedRow, 26), Cells(processedRow, 26)) = "=IF(VLOOKUP(Z7,rngVlookupData,1)=Z7,""Yes"","""")"
Range("AA5") = "=IF(VLOOKUP(Z7,rngVlookupData,1)=Z7,VLOOKUP(Z7,rngVlookupData,2),"""")"