在Java中的this
实例变量声明/初始化中使用final
关键字是否可以?
像这样:
private final SomeClass foo = new SomeClass(this);
当我试用它时它起作用了。因为它不是static
变量,我想它应该指的是一个特定的实例。但我不确定这是否可取,因此我想问这里。
编辑: 主类是Android Activity类,SomeClass-instance需要将此Activity作为Context。
答案 0 :(得分:4)
这样做“技术上有效”。实际上,this
指的是一个特定的实例 - 即包含SomeClass
实例的实例。
但我会不建议一般这样做。传递给构造函数的this
的确切行为和状态取决于细微的细节。请考虑以下示例:
class SomeClass
{
public SomeClass(DangerousSelfReference dangerousSelfReference)
{
System.out.println("State: ");
System.out.println(" a: "+dangerousSelfReference.getA());
System.out.println(" b: "+dangerousSelfReference.getB());
System.out.println(" c: "+dangerousSelfReference.getC());
System.out.println(" d: "+dangerousSelfReference.getD());
System.out.println(" ref: "+dangerousSelfReference.getRef());
}
}
public class DangerousSelfReference
{
public static void main(String[] args)
{
DangerousSelfReference d = new DangerousSelfReference();
}
private String a;
private String b = "b";
private final SomeClass ref = new SomeClass(this);
private final String c = "c";
private String d = "d";
DangerousSelfReference()
{
a = "a";
}
String getA()
{
return a;
}
String getB()
{
return b;
}
String getC()
{
return c;
}
String getD()
{
return d;
}
SomeClass getRef()
{
return ref;
}
}
我认为这可以成为一个整洁的求职面试问题,因为预测输出很难。令人惊讶的是,它打印
State:
a: null
b: b
c: c
d: null
ref: null
请注意,final
变量c
已初始化,但非最终变量d
尚未已初始化。与此相反,非最终变量b
(在<{em} SomeClass
实例之前声明为)已经初始化。
这些小事件总是有问题的,如果可能的话应该避免。
答案 1 :(得分:3)
private final SomeClass foo = new SomeClass(this);
private int bar = 42;
SomeClass构造函数将找到bar
为0。
所以不太好。
答案 2 :(得分:1)
我首先关注的是:你为什么需要这个?
通常,我不建议这样做,因为在更复杂的情况下它可能会有危险,其中SomeClass
构造取决于传递的this
对象的某些状态。
考虑一下,例如:
class SomeClass {
private Foo foo;
SomeClass(Foo foo) {
this.foo = foo;
// do something based on state of foo
// such as call
int len = foo.myString.length(); // <- this will throw NPE, because
// foo.myString is still null as Foo() constructor wasn't called yet
}
}
然后是你的Foo类:
class Foo {
String myString = null;
Foo() {/*constructor 1, perhaps calling init()*/
init();
}
Foo(...params) {/*constructor 2*/}
private void init() {
// some initialization
myString = "test String";
}
// Note: this constructor is called before any of Foo's
// constructos are invoked
// thus passed Foo "this" object is not initialized yet
// (contains defaults for all fields)
private final SomeClass someClass = new SomeClass(this);
}
答案 3 :(得分:-1)
因为它与Instance变量的final
关键字无关。
你正在做的是将封闭类的对象传递给SomeClass