thuộc tính tĩnh cuối cùng riêng tư vs thuộc tính cuối cùng riêng tư


305

Trong Java, sự khác biệt giữa:

private final static int NUMBER = 10;

private final int NUMBER = 10;

Cả hai đều privatefinal, sự khác biệt là staticthuộc tính.

Có gì tốt hơn? Và tại sao?


62
private static static -> chỉ tạo biến này một lần. private Final -> tạo biến này cho mọi đối tượng. Đầu tiên tiết kiệm bộ nhớ, đi cho nó.
dùng1923551

4
final staticcó nghĩa là biến này là một hằng số và chỉ liên kết với chính lớp đó, tức là "một biến không đổi trên mỗi lớp" trong khi đó finalcó nghĩa là "một biến không đổi cho mỗi thể hiện". Kết quả là, bạn không thể đặt một final staticbiến trong hàm tạo của lớp vì hàm tạo liên quan đến một thể hiện mới . (Bạn có thể tự mình thử và sẽ gặp lỗi)
LittleLittleQ

1
Bởi "không thể đặt biến tĩnh cuối cùng trong hàm tạo của lớp" Ý tôi là người ta không thể khởi tạo final staticbiến trong hàm tạo, cách duy nhất là sử dụng bộ khởi tạo tĩnh :)
LittleLittleQ

2
@ user1923551 Hiệu ứng được đảo ngược cho những thứ chỉ cần trong một khoảng thời gian giới hạn trong các ứng dụng lớn, trong các ứng dụng khan hiếm bộ nhớ hoặc khi sử dụng singleton. Có các công cụ tĩnh trong mỗi lớp sẽ dành một phần bộ nhớ (rất lớn) cho những thứ không cần thiết. Nó cũng có thể là một rò rỉ bộ nhớ để khai báo các đối tượng hoặc bộ sưu tập cuối cùng tĩnh.
Hy vọng hữu ích

Câu trả lời:


309

Nói chung, staticcó nghĩa là "được liên kết với chính loại đó, chứ không phải là một thể hiện của loại."

Điều đó có nghĩa là bạn có thể tham chiếu một biến tĩnh mà không bao giờ tạo một thể hiện của loại và bất kỳ mã nào đề cập đến biến đó đều tham chiếu đến cùng một dữ liệu. So sánh điều này với một biến đối tượng: trong trường hợp đó, có một phiên bản độc lập của biến cho mỗi thể hiện của lớp. Ví dụ:

Test x = new Test();
Test y = new Test();
x.instanceVariable = 10;
y.instanceVariable = 20;
System.out.println(x.instanceVariable);

in ra 10: y.instanceVariablex.instanceVariableriêng biệt, bởi vì xy đề cập đến các đối tượng khác nhau.

Bạn có thể tham khảo các thành viên tĩnh thông qua các tài liệu tham khảo, mặc dù đó là một ý tưởng tồi để làm như vậy. Nếu chúng ta đã làm:

Test x = new Test();
Test y = new Test();
x.staticVariable = 10;
y.staticVariable = 20;
System.out.println(x.staticVariable);

sau đó sẽ in ra 20 - chỉ có một biến, không phải một biến. Nó đã được rõ ràng hơn để viết này là:

Test x = new Test();
Test y = new Test();
Test.staticVariable = 10;
Test.staticVariable = 20;
System.out.println(Test.staticVariable);

Điều đó làm cho hành vi rõ ràng hơn nhiều. IDE hiện đại thường sẽ đề nghị thay đổi danh sách thứ hai thành thứ ba.

Không có lý do để có một khai báo nội tuyến khởi tạo giá trị như sau, vì mỗi trường hợp sẽ có NUMBERmột giá trị riêng nhưng luôn có cùng một giá trị (là bất biến và được khởi tạo bằng một chữ). Điều này giống với việc chỉ có một final staticbiến cho tất cả các trường hợp.

private final int NUMBER = 10;

Do đó, nếu nó không thể thay đổi, không có điểm nào có một bản sao cho mỗi phiên bản.

Nhưng, nó có ý nghĩa nếu được khởi tạo trong một hàm tạo như thế này:

// No initialization when is declared
private final int number;

public MyClass(int n) {
   // The variable can be assigned in the constructor, but then
   // not modified later.
   number = n;
}

Bây giờ, đối với mỗi trường hợp MyClass, chúng ta có thể có một giá trị khác nhau nhưng không thay đổi number.


10
Cho đến khi enum có sẵn trong Java 5, tĩnh cuối cùng là cách khai báo hằng.
Vineet Reynold

22
@Vineet: trận chung kết tĩnh vẫn là cách để khai báo hằng số nguyên thủy, trừ khi bạn có số lượng liệt kê của chúng =)
Chii

@Matthew: Có khả năng. Không phải cho một hằng số, nhưng đối với một số giá trị liên quan đến logic. Không phải là tôi thích singletons nhiều.
Jon Skeet

1
Một câu hỏi cấp tiến. Có đáng để sử dụng private finalhơn private static finalđể vắt kiệt / lấy lại bộ nhớ nhỏ đó từ lớp học không? Giả sử calculatorthiết bị có ram giới hạn nhưng nhiều tài nguyên CPU.
Giành chiến thắng Myo Htet

1
@WinMyoHtet: Nếu bạn sử dụng trường tĩnh, chỉ có một tổng số. Nếu bạn sử dụng một trường đối tượng, có một trường hợp. Sử dụng một trường tĩnh sẽ tốt hơn trừ khi bạn không có bất kỳ trường hợp nào, trong trường hợp đó dù sao nó cũng vô dụng.
Jon Skeet

38

Cho trận chung kết , nó có thể được chỉ định các giá trị khác nhau trong thời gian chạy khi khởi tạo. Ví dụ

Class Test{
  public final int a;
}

Test t1  = new Test();
t1.a = 10;
Test t2  = new Test();
t2.a = 20; //fixed

Do đó, mỗi trường hợp có giá trị khác nhau của trường a .

Đối với cuối cùng tĩnh , tất cả các phiên bản chia sẻ cùng một giá trị và không thể thay đổi sau khi khởi tạo lần đầu tiên.

Class TestStatic{
      public static final int a;
}

TestStatic t1  = new TestStatic();
t1.a = 10;
TestStatic t2  = new TestStatic();
t1.a = 20;   // ERROR, CAN'T BE ALTERED AFTER THE FIRST INITIALIZATION.

90
Điều này sẽ không được biên dịch! Một biến cuối cùng phải được gán một giá trị hoặc có một giá trị được gán trong các hàm tạo của nó. Câu trả lời này sẽ đúng nếu 2 hàm tạo được đưa ra, với mỗi lần gán 'a' cho một giá trị khác nhau.
MattC

14
Xác nhận, điều này sẽ không biên dịch. Như đã trình bày ở trên, biến đối tượng cuối cùng phải được khởi tạo trước khi hàm tạo kết thúc và các biến lớp cuối cùng phải được khởi tạo trước khi lớp được tạo (bạn có thể sử dụng khối tĩnh). Tại sao điều này có rất nhiều upvote?
Rudi Kershaw

như MattC đã chỉ ra, bạn không thể gán cho một biến cuối cùng sau khi tạo đối tượng đó - thực tế, bạn thậm chí không thể tạo một đối tượng mà không đưa ra các giá trị cho các biến cuối cùng của nó ...
jamesdeath123 30/1/2015

Chỉ trong trường hợp bất cứ ai vấp phải điều này, xin vui lòng làm theo câu trả lời của MattC.
Faz

Đây là những gì tôi nghĩ OP đã hỏi, tôi đã quên rằng trận chung kết có thể được gán một giá trị ngay lập tức nếu nó không được cung cấp khi khai báo.
Salsero69

34

Một staticbiến nằm trong bộ nhớ trong toàn bộ thời gian của ứng dụng và được khởi tạo trong khi tải lớp. Một staticbiến không được khởi tạo mỗi khi bạn xây dựng một newđối tượng. Nói chung là tốt hơn để sử dụng:

private static final int NUMBER = 10;

Tại sao? Điều này làm giảm dung lượng bộ nhớ cho mỗi ví dụ. Nó cũng có thể là thuận lợi cho truy cập bộ nhớ cache. Và nó chỉ có ý nghĩa: staticnên được sử dụng cho những thứ được chia sẻ trên tất cả các trường hợp (còn gọi là các đối tượng) thuộc một loại nhất định (aka class).


một biến tĩnh cũng được tạo ra trong thời gian chạy. Do đó, bạn có thể sử dụng biến hoặc phương thức đã nói trước khi đối tượng được tạo.
bboy

13
Theo quy ước mã hóa Java, tên của một biến cuối cùng tĩnh phải là chữ hoa.
starblue

@Martijn Courteaux, làm thế nào về một tình huống mà một lớp sẽ được sử dụng một lần trong suốt vòng đời của ứng dụng! private final intsẽ bị xóa khỏi bộ nhớ khi thể hiện sẽ được lưu trữ trong khi đó private static final intsẽ vẫn còn trong bộ nhớ trong suốt tuổi thọ của ứng dụng đó. Bạn đề nghị gì trong kịch bản trên?
MANN

@MANN: Đây là lý thuyết cao. Có nghĩa đen không có trường hợp sử dụng hữu ích cho điều đó. Điều này có thể có lợi nếu bạn có 50000 int vars trong một lớp. Ngay cả trong trường hợp này, điều này sẽ tiết kiệm tới 200kb bộ nhớ. Vì chúng ta đang nói Java, điều này dường như hoàn toàn không liên quan. Trong trường hợp các thiết bị quan trọng về bộ nhớ, trình biên dịch C hoặc C ++ phong nha sẽ luôn luôn xử lý các giá trị nguyên đó, loại bỏ hoàn toàn nhu cầu giải phóng bộ nhớ.
Martijn Courteaux

17

tĩnh có nghĩa là "liên kết với lớp"; không có nó, biến được liên kết với từng thể hiện của lớp. Nếu nó tĩnh, điều đó có nghĩa là bạn sẽ chỉ có một bộ nhớ; nếu không, bạn sẽ có một cái cho mỗi phiên bản bạn tạo. tĩnh có nghĩa là biến sẽ tồn tại trong bộ nhớ miễn là lớp được tải; không có nó, biến có thể là gc'd khi thể hiện của nó là.


Các biến sơ thẩm nhận gc'd bất cứ khi nào tất cả các tham chiếu / đối tượng đến nó chết, phải không?
Ruchir Baronia

Trường hợp là gc'd, nhưng thống kê được liên kết với các lớp, không phải trường hợp. Miễn là lớp vẫn còn trong bộ nhớ, bạn sẽ có thể tham khảo các thể hiện và phương thức tĩnh công khai của nó. Những người đi vào perm gen (hoặc bất cứ điều gì tương đương với JDK 8 của nó) và không phải là gc'd.
duffymo

Sai lầm. Nếu bạn có một tham chiếu đến một thể hiện trong bộ nhớ, bạn có thể truy cập các phương thức và thể hiện có sẵn của nó. Phần còn lại là sai. Bạn không hiểu sự khác biệt giữa một lớp và các thể hiện của nó.
duffymo

13

Đọc các câu trả lời tôi thấy không có bài kiểm tra thực sự thực sự đi đến điểm. Đây là 2 xu của tôi:

public class ConstTest
{

    private final int         value             = 10;
    private static final int  valueStatic       = 20;
    private final File        valueObject       = new File("");
    private static final File valueObjectStatic = new File("");

    public void printAddresses() {


        System.out.println("final int address " +
                ObjectUtils.identityToString(value));
        System.out.println("final static int address " +
                ObjectUtils.identityToString(valueStatic));
        System.out.println("final file address " + 
                ObjectUtils.identityToString(valueObject));
        System.out.println("final static file address " + 
                ObjectUtils.identityToString(valueObjectStatic));
    }


    public static void main(final String args[]) {


        final ConstTest firstObj = new ConstTest();
        final ConstTest sndObj = new ConstTest();

        firstObj.printAdresses();
        sndObj.printAdresses();
    }

}

Kết quả cho đối tượng đầu tiên:

final int address java.lang.Integer@6d9efb05
final static int address java.lang.Integer@60723d7c
final file address java.io.File@6c22c95b
final static file address java.io.File@5fd1acd3

Kết quả cho đối tượng thứ 2:

final int address java.lang.Integer@6d9efb05
final static int address java.lang.Integer@60723d7c
final file address java.io.File@3ea981ca
final static file address java.io.File@5fd1acd3

Phần kết luận :

Như tôi nghĩ java tạo ra sự khác biệt giữa các kiểu nguyên thủy và các loại khác. Các kiểu nguyên thủy trong Java luôn được "lưu trữ", giống nhau cho các chuỗi ký tự (không phải các đối tượng Chuỗi mới), do đó không có sự khác biệt giữa các thành viên tĩnh và không tĩnh.

Tuy nhiên, có một sự trùng lặp bộ nhớ cho các thành viên không tĩnh nếu chúng không phải là thể hiện của kiểu nguyên thủy.

Thay đổi giá trị của valueStatic thành 10 thậm chí sẽ đi xa hơn vì Java sẽ cung cấp cùng một địa chỉ cho hai biến int.


2
Autoboxing của 'int' -> Integer đang gây nhầm lẫn ở đây. Bạn đang thấy rằng hộp thư tự động của một số giá trị int (nhỏ) dẫn đến cùng một đối tượng Integer.
dkneller

@StackHola @dkneller Thật vậy, autoboxing là một chi tiết rất quan trọng xảy ra ở đây. Chữ ký là ObjectUtils.identityToString(Object). (Bên cạnh đó, Java không có thông qua tham chiếu nào). Một thử nghiệm hữu ích thực sự sẽ là phân bổ hai đối tượng và thay đổi giá trị của một public final int FOO = 10biến bằng cách sử dụng các phản xạ Java theo cách bắt buộc. Sau đó kiểm tra xem đối tượng khác cũng đã thay đổi giá trị của nó.
Martijn Courteaux

11

Mặc dù các câu trả lời khác dường như cho thấy khá rõ ràng rằng thường không có lý do để sử dụng các hằng số không tĩnh, tôi không thể tìm thấy bất cứ ai chỉ ra rằng có thể có nhiều trường hợp khác nhau với các giá trị khác nhau trên các biến không đổi của chúng.

Hãy xem xét ví dụ sau:

public class TestClass {
    private final static double NUMBER = Math.random();

    public TestClass () {
        System.out.println(NUMBER);
    }
}

Tạo ba phiên bản TestClass sẽ in cùng một giá trị ngẫu nhiên ba lần, vì chỉ một giá trị được tạo và được lưu vào hằng số tĩnh.

Tuy nhiên, khi thử ví dụ sau:

public class TestClass {
    private final double NUMBER = Math.random();

    public TestClass () {
        System.out.println(NUMBER);
    }
}

Tạo ba phiên bản TestClass bây giờ sẽ in ba giá trị ngẫu nhiên khác nhau, vì mỗi phiên bản có giá trị không đổi được tạo ngẫu nhiên riêng.

Tôi không thể nghĩ về bất kỳ tình huống nào sẽ thực sự hữu ích khi có các giá trị không đổi khác nhau trong các trường hợp khác nhau, nhưng tôi hy vọng điều này sẽ giúp chỉ ra rằng có một sự khác biệt rõ ràng giữa trận chung kết tĩnh và không tĩnh.


2

Như Jon đã nói, một biến tĩnh, còn được gọi là biến lớp, là một biến tồn tại trên các thể hiện của một lớp.

Tôi tìm thấy một ví dụ về điều này ở đây :

public class StaticVariable
{
  static int noOfInstances;
  StaticVariable()
  {
    noOfInstances++;
  }
  public static void main(String[] args)
  {
    StaticVariable sv1 = new StaticVariable();
    System.out.println("No. of instances for sv1 : " + sv1.noOfInstances);

    StaticVariable sv2 = new StaticVariable();
    System.out.println("No. of instances for sv1 : "  + sv1.noOfInstances);
    System.out.println("No. of instances for st2 : "  + sv2.noOfInstances);

    StaticVariable sv3 = new StaticVariable();
    System.out.println("No. of instances for sv1 : "  + sv1.noOfInstances);
    System.out.println("No. of instances for sv2 : "  + sv2.noOfInstances);
    System.out.println("No. of instances for sv3 : "  + sv3.noOfInstances);
  }
}

Đầu ra của chương trình được đưa ra dưới đây:

Như chúng ta có thể thấy trong ví dụ này, mỗi đối tượng có một bản sao của biến lớp.

C:\java>java StaticVariable
No. of instances for sv1 : 1
No. of instances for sv1 : 2
No. of instances for st2 : 2
No. of instances for sv1 : 3
No. of instances for sv2 : 3
No. of instances for sv3 : 3

2

Từ các thử nghiệm tôi đã thực hiện, các biến cuối cùng tĩnh không giống với các biến cuối cùng (không tĩnh)! Các biến cuối cùng (không tĩnh) có thể khác nhau từ đối tượng này sang đối tượng !!! Nhưng đó chỉ là khi việc khởi tạo được thực hiện trong hàm tạo! (Nếu nó không được khởi tạo từ hàm tạo thì đó chỉ là sự lãng phí bộ nhớ vì nó tạo các biến cuối cùng cho mọi đối tượng được tạo mà không thể thay đổi.)

Ví dụ:

class A
{
    final int f;
    static final int sf = 5;

    A(int num)
    {
        this.f = num;
    }

    void show()
    {
        System.out.printf("About Object: %s\n Final: %d\n Static Final: %d\n\n", this.toString(), this.f, sf);
    }

    public static void main(String[] args)
    {
        A ob1 = new A(14);
        ob1.show();

        A ob2 = new A(21);
        ob2.show();

    }
}

Những gì hiển thị trên màn hình là:

Về đối tượng: Chung kết A @ addbf1: 14 Chung kết tĩnh: 5

Về đối tượng: A @ 530daa Chung kết: 21 Chung kết tĩnh: 5

Sinh viên CNTT năm thứ nhất ẩn danh, Hy Lạp


Đây không phải là một câu trả lời :(
Sanjaya Pandey

2

Hơn nữa với câu trả lời của Jon nếu bạn sử dụng cuối cùng tĩnh, nó sẽ hoạt động như một loại "định nghĩa". Khi bạn biên dịch lớp sử dụng nó, nó sẽ nằm trong tệp. Class được biên dịch. Kiểm tra chủ đề của tôi về nó ở đây .

Đối với mục tiêu chính của bạn: Nếu bạn không sử dụng SỐ khác nhau trong các trường hợp khác nhau của lớp, tôi sẽ khuyên bạn nên sử dụng cuối cùng và tĩnh. (Bạn chỉ cần lưu ý không sao chép các tệp lớp đã biên dịch mà không xem xét các rắc rối có thể xảy ra như trường hợp nghiên cứu của tôi mô tả. Hầu hết các trường hợp này không xảy ra, đừng lo lắng :))

Để chỉ cho bạn cách sử dụng các giá trị khác nhau trong các trường hợp, hãy kiểm tra mã này:

public class JustFinalAttr {
  public final int Number;

  public JustFinalAttr(int a){
    Number=a;
  }
}

...System.out.println(new JustFinalAttr(4).Number);

Tôi đã có một liên kết ở đây để so sánh chi tiết. Tôi xin lỗi các bạn, điều này đã được kiểm duyệt tôi đoán.
BlondCode

Liên kết đã trở lại. Một biên tập viên đã đưa nó ra như đã chết. Nó dường như được sống bây giờ.
Erick G. Hagstrom

2

Đây là hai xu của tôi:

final           String CENT_1 = new Random().nextInt(2) == 0 ? "HEADS" : "TAILS";
final   static  String CENT_2 = new Random().nextInt(2) == 0 ? "HEADS" : "TAILS";

Thí dụ:

package test;

public class Test {

    final long OBJECT_ID = new Random().nextLong();
    final static long CLASSS_ID = new Random().nextLong();

    public static void main(String[] args) {
        Test[] test = new Test[5];
        for (int i = 0; i < test.length; i++){
            test[i] = new Test();
            System.out.println("Class id: "+test[i].CLASSS_ID);//<- Always the same value
            System.out.println("Object id: "+test[i].OBJECT_ID);//<- Always different
        }
    }
}

Điều quan trọng là các biến và hàm có thể trả về các giá trị khác nhau. Do đó, các biến cuối cùng có thể được gán với các giá trị khác nhau.


Bạn có thể vui lòng giải thích về cái nào tốt hơn và tại sao?
Daniel

2

Chỉ là một ví dụ đơn giản khác để hiểu cách sử dụng các biến tĩnh, cuối cùng tĩnh, cuối cùng. Mã ý kiến ​​có lời giải thích thích hợp.

public class City {

    // base price that is always same for all objects[For all cities].
    private static double iphone_base_price = 10000;

    // this is total price = iphone_base_price+iphone_diff;
    private double iphone_citi_price;

    // extra price added to iphone_base_price. It is constant per city. Every
    // city has its own difference defined,
    private final double iphone_diff;

    private String cityName = "";

    // static final will be accessible everywhere within the class but cant be
    // changed once initialized.
    private static final String countryName = "India";

    public City(String cityName, double iphone_diff) {
        super();
        this.iphone_diff = iphone_diff;
        iphone_citi_price = iphone_base_price + iphone_diff;
        this.cityName = cityName;

    }

    /**
     * get phone price
     * 
     * @return
     */
    private double getPrice() {

        return iphone_citi_price;
    }

    /**
     * Get city name
     * 
     * @return
     */
    private String getCityName() {

        return cityName;
    }

    public static void main(String[] args) {

        // 300 is the
        City newyork = new City("Newyork", 300);
        System.out.println(newyork.getPrice() + "  " + newyork.getCityName());

        City california = new City("California", 800);
        System.out.println(california.getPrice() + "  " + california.getCityName());

        // We cant write below statement as a final variable can not be
        // reassigned
        // california.iphone_diff=1000; //************************

        // base price is defined for a class and not per instances.
        // For any number of object creation, static variable's value would be the same
        // for all instances until and unless changed.
        // Also it is accessible anywhere inside a class.
        iphone_base_price = 9000;

        City delhi = new City("delhi", 400);
        System.out.println(delhi.getPrice() + "  " + delhi.getCityName());

        City moscow = new City("delhi", 500);
        System.out.println(moscow.getPrice() + "  " + moscow.getCityName());

        // Here countryName is accessible as it is static but we can not change it as it is final as well. 
        //Something are meant to be accessible with no permission to modify it. 
        //Try un-commenting below statements
        System.out.println(countryName);

        // countryName="INDIA";
        // System.out.println(countryName);

    }

}

1

rất ít và tĩnh

Không có nhiều khác biệt vì cả hai đều là hằng số. Đối với hầu hết các đối tượng dữ liệu lớp, tĩnh có nghĩa là một cái gì đó được liên kết với chính lớp đó, chỉ có một bản sao cho dù có bao nhiêu đối tượng được tạo mới.

Vì nó là một hằng số, nó thực sự có thể không được lưu trữ trong cả lớp hoặc trong một thể hiện, nhưng trình biên dịch vẫn sẽ không cho phép bạn truy cập các đối tượng thể hiện từ một phương thức tĩnh, ngay cả khi nó biết chúng sẽ là gì. Sự tồn tại của API phản chiếu cũng có thể yêu cầu một số công việc vô nghĩa nếu bạn không làm cho nó tĩnh.


1

Vì một biến trong một lớp được khai báo là cuối cùng VÀ được khởi tạo trong cùng một lệnh, nên hoàn toàn không có lý do gì để không khai báo nó là tĩnh, vì nó sẽ có cùng giá trị cho dù là trường hợp nào. Vì vậy, tất cả các phiên bản có thể chia sẻ cùng một địa chỉ bộ nhớ cho một giá trị, do đó tiết kiệm thời gian xử lý bằng cách loại bỏ nhu cầu tạo biến mới cho mỗi phiên bản và lưu bộ nhớ bằng cách chia sẻ 1 địa chỉ chung.


1

private static Final sẽ được coi là hằng số và hằng số chỉ có thể được truy cập trong lớp này. Vì, từ khóa tĩnh bao gồm, giá trị sẽ không đổi cho tất cả các đối tượng của lớp.

giá trị biến cuối cùng riêng tư sẽ giống như hằng số trên mỗi đối tượng.

Bạn có thể tham khảo java.lang.String hoặc tìm ví dụ bên dưới.

public final class Foo
{

    private final int i;
    private static final int j=20;

    public Foo(int val){
        this.i=val;
    }

    public static void main(String[] args) {
        Foo foo1= new Foo(10);

        Foo foo2= new Foo(40);

        System.out.println(foo1.i);
        System.out.println(foo2.i);
        System.out.println(check.j);
    }
}

// Kết quả:

10
40
20

0

Một tĩnh là cùng một thành viên trên tất cả các thể hiện của lớp và chính lớp đó.
Không tĩnh là một cho mọi trường hợp (đối tượng), vì vậy trong trường hợp chính xác của bạn , sẽ lãng phí bộ nhớ nếu bạn không đặt tĩnh.


0

Nếu bạn đánh dấu biến tĩnh này như bạn biết, bạn sẽ yêu cầu các phương thức tĩnh truy cập lại các giá trị này, điều này sẽ hữu ích nếu bạn đã nghĩ đến việc chỉ sử dụng các biến này trong các phương thức tĩnh. Nếu điều này là như vậy thì đây sẽ là một trong những tốt nhất.

Tuy nhiên, bạn có thể biến biến thành công khai vì không ai có thể sửa đổi nó giống như "System.out", nó lại phụ thuộc vào ý định của bạn và những gì bạn muốn đạt được.


1
Các phương thức tĩnh sẽ không được yêu cầu để truy cập các biến tĩnh - Tôi nghĩ rằng bạn đang nghĩ đến việc "truy cập các biến thể hiện từ các phương thức tĩnh" (không được phép).
ataulm

0

Hãy nói rằng nếu lớp sẽ không có nhiều hơn một thể hiện, thì cái nào sẽ chiếm nhiều bộ nhớ hơn:

private int int ID = 250; hoặc ID riêng cuối cùng = 250;

Tôi đã hiểu rằng tĩnh sẽ chỉ loại lớp chỉ có một bản sao trong bộ nhớ và không tĩnh sẽ ở một vị trí bộ nhớ mới cho mỗi biến thể hiện. Tuy nhiên, bên trong nếu chúng ta chỉ so sánh 1 thể hiện của cùng một lớp bao giờ (nghĩa là nhiều hơn 1 thể hiện sẽ không được tạo), thì có bất kỳ chi phí nào về không gian được sử dụng bởi 1 biến cuối cùng không?


1
Xin đừng lặp lại, những câu trả lời khác đã được đề cập.
người dùng không xác định

0

Biến tĩnh thuộc về lớp (có nghĩa là tất cả các đối tượng chia sẻ biến đó). Biến không tĩnh thuộc về từng đối tượng.

public class ExperimentFinal {

private final int a;
private static final int b = 999; 

public ExperimentFinal(int a) {
    super();
    this.a = a;
}
public int getA() {
    return a;
}
public int getB() {
    return b;
}
public void print(int a, int b) {
    System.out.println("final int: " + a + " \nstatic final int: " + b);
}
public static void main(String[] args) {
    ExperimentFinal test = new ExperimentFinal(9);
    test.print(test.getA(), test.getB());
} }

Như bạn có thể thấy ở ví dụ trên, đối với "int int", chúng ta có thể gán biến của mình cho từng thể hiện (đối tượng) của lớp, tuy nhiên đối với "static Final int", chúng ta nên gán một biến trong lớp (biến tĩnh thuộc về lớp ).


0

Nếu bạn sử dụng tĩnh, giá trị của biến sẽ giống nhau trong tất cả các phiên bản của bạn, nếu thay đổi trong một trường hợp thì các trường hợp khác cũng sẽ thay đổi.


0

Final: Một khi một biến cuối cùng đã được gán, nó luôn chứa cùng một giá trị. Bất cứ nơi nào biến là tĩnh hoặc không tĩnh: nó sẽ chỉ là một biến cho tất cả các trường hợp được khởi tạo một lần trong Bộ nhớ


-1

Điều này có thể giúp

public class LengthDemo {
public static void main(String[] args) {
    Rectangle box = new Rectangle();
    System.out.println("Sending the value 10.0 "
            + "to the setLength method.");
    box.setLength(10.0);
    System.out.println("Done.");
    }
}

1
chắc chắn đó là một câu trả lời cho quesiton này?
mikus

-2

Từ khóa "tĩnh" làm cho thuộc tính biến của lớp thay vì các thể hiện riêng lẻ của lớp. Sẽ có một bản sao của biến đó được chia sẻ giữa tất cả các thể hiện của lớp đó. Mọi thay đổi về trạng thái của biến tĩnh sẽ được phản ánh trên tất cả các trường hợp. Thêm cuối cùng vào tĩnh và chúng ta nhận được một biến đã được khởi tạo một lần và cho tất cả tại thời điểm tải lớp và không thể thay đổi sau đó bởi bất kỳ trường hợp nào của lớp. Các biến cuối cùng tĩnh cần được khởi tạo tại thời điểm khai báo khác, chúng tôi có lỗi thời gian biên dịch. Đối với trường đối tượng riêng có liên quan, nó đề cập đến thuộc tính / trạng thái của một đối tượng / thể hiện của một lớp. Mỗi thể hiện / đối tượng của lớp sẽ có bản sao biến đối tượng riêng. Khi biến thể hiện được khai báo cuối cùng, nó có nghĩa là chúng ta không thể thay đổi giá trị của nó trong trường hợp này. Để làm điều này, chúng ta cần khởi tạo biến cuối cùng trong khai báo hoặc trong hàm tạo. Nếu nó không được thực hiện ở một trong hai biến đó, lỗi thời gian biên dịch sẽ hiển thị. Sau khi khởi tạo, nếu bạn cố gắng gán lại một giá trị, bạn sẽ gặp lỗi thời gian biên dịch. Sử dụng các biến cuối cùng tĩnh trong đó dữ liệu sẽ được chia sẻ trên tất cả các phiên bản của lớp và bạn muốn dữ liệu chỉ được đọc. Sử dụng biến cuối cùng của cá thể nếu bạn muốn biểu diễn một số dữ liệu thuộc về từng cá thể của lớp nhưng một lần lưu trữ không thể thay đổi. Việc sử dụng từ khóa tĩnh và ví dụ phụ thuộc vào nhu cầu thiết kế của bạn và dữ liệu đó đại diện cho miền nào. Nếu dữ liệu được sử dụng trên các thể hiện của lớp thì không cần tham chiếu các bản sao / bộ nhớ riêng cho từng đối tượng. Để làm điều này, chúng ta cần khởi tạo biến cuối cùng trong khai báo hoặc trong hàm tạo. Nếu nó không được thực hiện ở một trong hai biến đó, lỗi thời gian biên dịch sẽ hiển thị. Sau khi khởi tạo, nếu bạn cố gắng gán lại một giá trị, bạn sẽ gặp lỗi thời gian biên dịch. Sử dụng các biến cuối cùng tĩnh trong đó dữ liệu sẽ được chia sẻ trên tất cả các phiên bản của lớp và bạn muốn dữ liệu chỉ được đọc. Sử dụng biến cuối cùng của cá thể nếu bạn muốn biểu diễn một số dữ liệu thuộc về từng cá thể của lớp nhưng một lần lưu trữ không thể thay đổi. Việc sử dụng từ khóa tĩnh và ví dụ phụ thuộc vào nhu cầu thiết kế của bạn và dữ liệu đó đại diện cho miền nào. Nếu dữ liệu được sử dụng trên các thể hiện của lớp thì không cần tham chiếu các bản sao / bộ nhớ riêng cho từng đối tượng. Để làm điều này, chúng ta cần khởi tạo biến cuối cùng trong khai báo hoặc trong hàm tạo. Nếu nó không được thực hiện ở một trong hai biến đó, lỗi thời gian biên dịch sẽ hiển thị. Sau khi khởi tạo, nếu bạn cố gắng gán lại một giá trị, bạn sẽ gặp lỗi thời gian biên dịch. Sử dụng các biến cuối cùng tĩnh trong đó dữ liệu sẽ được chia sẻ trên tất cả các phiên bản của lớp và bạn muốn dữ liệu chỉ được đọc. Sử dụng biến cuối cùng của cá thể nếu bạn muốn biểu diễn một số dữ liệu thuộc về từng cá thể của lớp nhưng một lần lưu trữ không thể thay đổi. Việc sử dụng từ khóa tĩnh và ví dụ phụ thuộc vào nhu cầu thiết kế của bạn và dữ liệu đó đại diện cho miền nào. Nếu dữ liệu được sử dụng trên các thể hiện của lớp thì không cần tham chiếu các bản sao / bộ nhớ riêng cho từng đối tượng. Nếu nó không được thực hiện ở một trong hai, lỗi thời gian biên dịch sẽ hiển thị. Sau khi khởi tạo, nếu bạn cố gắng gán lại một giá trị, bạn sẽ gặp lỗi thời gian biên dịch. Sử dụng các biến cuối cùng tĩnh trong đó dữ liệu sẽ được chia sẻ trên tất cả các phiên bản của lớp và bạn muốn dữ liệu chỉ được đọc. Sử dụng biến cuối cùng của cá thể nếu bạn muốn biểu diễn một số dữ liệu thuộc về từng cá thể của lớp nhưng một lần lưu trữ không thể thay đổi. Việc sử dụng từ khóa tĩnh và ví dụ phụ thuộc vào nhu cầu thiết kế của bạn và dữ liệu đó đại diện cho miền nào. Nếu dữ liệu được sử dụng trên các thể hiện của lớp thì không cần tham chiếu các bản sao / bộ nhớ riêng cho từng đối tượng. Nếu nó không được thực hiện ở một trong hai, lỗi thời gian biên dịch sẽ hiển thị. Sau khi khởi tạo, nếu bạn cố gắng gán lại một giá trị, bạn sẽ gặp lỗi thời gian biên dịch. Sử dụng các biến cuối cùng tĩnh trong đó dữ liệu sẽ được chia sẻ trên tất cả các phiên bản của lớp và bạn muốn dữ liệu chỉ được đọc. Sử dụng biến cuối cùng của cá thể nếu bạn muốn biểu diễn một số dữ liệu thuộc về từng cá thể của lớp nhưng một lần lưu trữ không thể thay đổi. Việc sử dụng từ khóa tĩnh và ví dụ phụ thuộc vào nhu cầu thiết kế của bạn và dữ liệu đó đại diện cho miền nào. Nếu dữ liệu được sử dụng trên các thể hiện của lớp thì không cần tham chiếu các bản sao / bộ nhớ riêng cho từng đối tượng. Sử dụng các biến cuối cùng tĩnh trong đó dữ liệu sẽ được chia sẻ trên tất cả các phiên bản của lớp và bạn muốn dữ liệu chỉ được đọc. Sử dụng biến cuối cùng của cá thể nếu bạn muốn biểu diễn một số dữ liệu thuộc về từng cá thể của lớp nhưng một lần lưu trữ không thể thay đổi. Việc sử dụng từ khóa tĩnh và ví dụ phụ thuộc vào nhu cầu thiết kế của bạn và dữ liệu đó đại diện cho miền nào. Nếu dữ liệu được sử dụng trên các thể hiện của lớp thì không cần tham chiếu các bản sao / bộ nhớ riêng cho từng đối tượng. Sử dụng các biến cuối cùng tĩnh trong đó dữ liệu sẽ được chia sẻ trên tất cả các phiên bản của lớp và bạn muốn dữ liệu chỉ được đọc. Sử dụng biến cuối cùng của cá thể nếu bạn muốn biểu diễn một số dữ liệu thuộc về từng cá thể của lớp nhưng một lần lưu trữ không thể thay đổi. Việc sử dụng từ khóa tĩnh và ví dụ phụ thuộc vào nhu cầu thiết kế của bạn và dữ liệu đó đại diện cho miền nào. Nếu dữ liệu được sử dụng trên các thể hiện của lớp thì không cần tham chiếu các bản sao / bộ nhớ riêng cho từng đối tượng. Việc sử dụng từ khóa tĩnh và ví dụ phụ thuộc vào nhu cầu thiết kế của bạn và dữ liệu đó đại diện cho miền nào. Nếu dữ liệu được sử dụng trên các thể hiện của lớp thì không cần tham chiếu các bản sao / bộ nhớ riêng cho từng đối tượng. Việc sử dụng từ khóa tĩnh và ví dụ phụ thuộc vào nhu cầu thiết kế của bạn và dữ liệu đó đại diện cho miền nào. Nếu dữ liệu được sử dụng trên các thể hiện của lớp thì không cần tham chiếu các bản sao / bộ nhớ riêng cho từng đối tượng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.