如何用final实现static?

时间:2017-04-14 08:17:06

标签: java oop

我对finalstatic关键字的含义感到困惑。这是因为,据我所知,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); 
    }
}

请解释它在内部是如何运作的。

4 个答案:

答案 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()关键字表示即使您没有实例化该类,该变量也可用。例如,在您的示例中,即使您从未调用staticyourClass.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语句,都会导致错误。