我对final
和static
关键字的含义感到困惑。这是因为,据我所知,static
在课堂上创建了一个单独的内存。只能从static
方法访问static
字段。那么,当我在Test构造函数中声明list
时,为什么没有错误?
第一个问题:
public Test() {
list = new ArrayList();
list.add("foo");
}
当我宣布
时public class Test {
private static List list;
public Test() {
list = new ArrayList();
list.add("foo");
}
public static void main(String [] args) throws IOException{
list = new ArrayList();
Test t = new Test();
t.list.add("add");
System.out.print("Hello " + t.list);
}
}
工作正常。但是当我使用final
添加static
时,它不起作用。
第二个问题:
public class Test {
private static final List list;
public Test() {
list = new ArrayList();
list.add("foo");
}
public static void main(String [] args) throws IOException{
list = new ArrayList();
Test t = new Test();
t.list.add("add");
System.out.print("Hello" + t.list);
}
}
请解释它在内部是如何运作的。
答案 0 :(得分:2)
<强>问题-1 强>
将 static 关键字与对象一起使用,可以在容器类的所有对象之间共享同一个副本。因此,如果您初始化,重新分配 static 对象,它会更改该类的所有对象。 您可以使用 static 引用创建新对象,或者根据需要重新分配它,但它将反映到容器类的所有现有对象和新对象。您不能为特定容器类对象分配不同的值。 静态变量可以在实例化容器类之前随时随地访问,使用类名后跟变量名。 关于访问静态变量,您可以从任何静态或非静态方法访问它。但是在 static 方法中,您只能使用 static 变量或仅在该方法中声明的变量。
<强>问题-2 强>
将 final 关键字与对象一起使用,告诉编译器应该只有一个,并且单个对象/值应与声明为 final 的引用相关联。 最终对象/变量只应在声明时初始化一次。其值/引用对象无法进一步更改/重新分配。我们在C ++中称之为常量变量;
希望它有所帮助。
干杯.. !!
答案 1 :(得分:1)
检查以下代码和附加的评论。
public class Test {
// this can be set only once and only from the static block
private static final List listStaticFinal;
// this is initialized when declared
private static final List listStaticFinalInitialized = new ArrayList();
// this can be set many times from multiple places
private static List listStatic;
// this is initialized when declared
private static List listStaticInitialized = new ArrayList();
static {
// can set only once from here
listStaticFinal = new ArrayList();
// can be set also from here
listStatic = new ArrayList();
}
public Test() {
// can be set also from here
listStatic = new ArrayList();
}
public static void main(String[] args) {
// can be set also from here
listStatic = new ArrayList();
}
}
注意:您只能在静态块中设置静态最终字段。
注意:Java没有静态类的概念。如果您希望您的类的行为类似于静态类,那么您可以将构造函数标记为私有。
注意:编写静态字段时,还要考虑使用代码的上下文并适当记录代码。例如,您的代码可能在多线程场景中使用。
注意:编写静态字段时,还要考虑如何测试代码。静态可能会造成模拟相应代码的困难。
答案 2 :(得分:1)
由于 final 变量在启动期间只能初始化一次,这就是允许构造函数初始化变量的原因。这里我们还得到了 static ,这意味着你必须在类加载期间初始化变量。这可以使用静态初始化程序块来完成。
静态{ list = new ArrayList(); }
答案 3 :(得分:0)
关于您的第一个问题,new yourClass()
关键字表示即使您没有实例化该类,该变量也可用。例如,在您的示例中,即使您从未调用static
,yourClass.list
也会引用列表。如果您在设置课程之前遗漏了final
关键字,public Test(){
list = new ArrayList();
}
尚不存在。
private final List list = new ArrayList();
关键字用于声明常量。也就是说,在变量初始化(第一次为其赋值)之后,在构造函数中
list = …
或在声明String url = user.getPhotoUrl(); //"gs://bucket/images/stars.jpg"
// Create a reference to a file from a Google Cloud Storage URI
StorageReference gsReference = storage.getReferenceFromUrl(url);
gsReference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
@Override
public void onSuccess(Uri uri) {
// handle success
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
// Handle any errors
}
});
之后立即,它是不可变的。任何改变它的尝试,例如使用另一个euler
语句,都会导致错误。