构造函数用于初始化一个值,并在创建类实例时将其赋值给类变量,对吗?
public class Joke{
private String jokeSetup;
private String jokePunchLine;
public Joke(String jokeSetup , String jokePunchLine){
this.jokeSetup=jokeSetup;
this.jokePunchLine=jokePunchLine;
}
}
请考虑以下事项:
public Joke(String jokeSetup , String jokePunchLine)
是否创建了另一个具有相同名称的变量?
如果是这样,为什么会将其分配给前jokeSetup
和jokePunchLine
值?
PS:这段代码不是由我创建的。它是在我正在学习Java的视频中显示的。
答案 0 :(得分:8)
构造函数的目的是初始化刚刚创建的对象,例如填充其实例字段(也称为实例变量)。构造函数中使用this
来引用构造函数初始化的实例。
在示例构造函数中,您有参数和实例字段。构造函数正在获取参数的值并将这些值分配给实例字段:
public Joke(String jokeSetup , String jokePunchLine)
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---- Declares parameters this
// constructor accepts when
// called
{
// vvvvvvvvv------------ parameter
this.jokeSetup=jokeSetup;
// ^^^^^^^^^^^^^^---------------------- instance field
// vvvvvvvvvvvvv---- parameter
this.jokePunchLine=jokePunchLine;
// ^^^^^^^^^^^^^^^^^^------------------ instance field
}
构造函数可以初始化具有常量值的实例字段,或者间接使用参数值(例如,查找某些内容)等。它并不总是直接的一对一分配,因为它是在你的例子中。
在您的示例中,参数与实例字段具有相同的名称,但这不是必需的。例如,这个构造函数与您的构造函数完全相同:
public Joke(String theJokeSetup , String theJokePunchLine)
// ^---------------------^---------- Note the name changes
{
// vvvvvvvvvvvv------------ parameter
this.jokeSetup = theJokeSetup;
// ^^^^^^^^^^^^^^--------------------------- instance field
// vvvvvvvvvvvvvvvv---- parameter
this.jokePunchLine = theJokePunchLine;
// ^^^^^^^^^^^^^^^^^^----------------------- instance field
}
Java允许您在引用实例字段时不使用this.
部分,只需单独使用字段名称(例如jokeSetup
而不是this.jokeSetup
)。但是,除非重命名参数,否则不能在构造函数中执行此操作,因为它们与实例字段具有相同的名称,因此构造函数中的jokeSetup
是参数,而不是字段。当出现类似的冲突时,最本地标识符优先(在构造函数中,参数是最本地的)。
如果没有冲突,无论您是否使用this.
部分,都是一种风格问题。 (我总是使用this.
,我发现它更清楚。)例如,这里是该构造函数的另一个版本,与原版完全相同:
public Joke(String theJokeSetup , String theJokePunchLine)
// ^---------------------^---------- Note the name changes
{
// vvvvvvvvvvvv------------ parameter
jokeSetup = theJokeSetup;
// ^^^^^^^^^--------------------------- instance field
// vvvvvvvvvvvvvvvv---- parameter
jokePunchLine = theJokePunchLine;
// ^^^^^^^^^^^^^----------------------- instance field
}
我之所以提到这一点是因为,当没有冲突时,这只是一种风格问题,你有时会看到这种风格。
答案 1 :(得分:2)
该类有一个名为jokeSetup的字段。 该方法具有与该字段 shadow 同名的参数。
所以本质上有两个同名的变量。
使用这个可以再次区分两个同名的不同用法,因为 this.whatever 总是表示相应的字段。
你钉了它:阴影实际上不是一个好主意。但这种“模式”在Java中实际上很常见。您可以通过为参数指定一个不同的名称来避免它,例如_jokeSetup,但偏离常规做法也是不好的做法。
答案 2 :(得分:2)
参数化构造函数可用于在创建变量时将值初始化为变量。当参数和变量名称相同时,在这种情况下要区分两者,我们使用 this 关键字。 此 keyworord始终引用方法或类的局部变量。
答案 3 :(得分:1)
Java对符号名称有隐含的上下文;非静态上下文的类实例(即this
)和静态的类(例如Joke
)。
这使您可以在符号名称没有冲突时省略上下文。例如
public String getJokeSetup() {
return jokeSetup; // no "this." required, it's implied
}
如果名称存在冲突,例如名称与字段相同的方法参数的情况,则需要明确定义上下文,例如
public void setJokeSetup(final String jokeSetup) {
// you must prefix the field with "this." to differentiate it from the argument
this.jokeSetup = jokeSetup;
}
最后,这是一个避免符号名称冲突的例子
public void setJokeSetup(final String js) {
jokeSetup = js;
}
将参数命名为与它们对应的字段相同是相当典型的,但您肯定不会受到这种约定的限制。