Việc sử dụng một biến tĩnh riêng trong Java là gì?


156

Nếu một biến được khai báo là public static varName;, thì tôi có thể truy cập nó từ bất cứ đâu dưới dạng ClassName.varName. Tôi cũng biết rằng các thành viên tĩnh được chia sẻ bởi tất cả các thể hiện của một lớp và không được phân bổ lại trong mỗi trường hợp.

Là khai báo một biến là private static varName;bất kỳ khác với khai báo một biến private varName;?

Trong cả hai trường hợp, nó không thể được truy cập như ClassName.varNamehoặc ClassInstance.varNametừ bất kỳ lớp nào khác.

Có khai báo biến là tĩnh cung cấp cho nó các thuộc tính đặc biệt khác không?


5
Tên biến Java không thể chứa dấu gạch ngang (-).
Martijn Courteaux

Câu trả lời:


127

Tất nhiên nó có thể được truy cập dưới dạng ClassName.var_name, nhưng chỉ từ bên trong lớp được định nghĩa - đó là vì nó được định nghĩa là private.

public statichoặc private staticcác biến thường được sử dụng cho hằng số. Ví dụ, nhiều người không thích các hằng số "mã cứng" trong mã của họ; họ muốn tạo một public statichoặc một private staticbiến với một tên có ý nghĩa và sử dụng nó trong mã của họ, điều này sẽ làm cho mã dễ đọc hơn. (Bạn cũng nên tạo các hằng số như vậy final).

Ví dụ:

public class Example {
    private final static String JDBC_URL = "jdbc:mysql://localhost/shopdb";
    private final static String JDBC_USERNAME = "username";
    private final static String JDBC_PASSWORD = "password";

    public static void main(String[] args) {
        Connection conn = DriverManager.getConnection(JDBC_URL,
                                         JDBC_USERNAME, JDBC_PASSWORD);

        // ...
    }
}

Cho dù bạn thực hiện nó publichay privatephụ thuộc vào việc bạn muốn các biến được hiển thị bên ngoài lớp hay không.


6
Những gì cần thiết của việc truy cập là ClassName.var_nam? Nơi tôi có thể truy cập trực tiếp: var_namtrong lớp
Vaibhav Jani

12
Không cần thiết phải truy cập nó thông qua tên lớp, nhưng một số người nghĩ rằng đó là phong cách tốt, để phân biệt nó với một biến không tĩnh.
Jesper

5
những gì cần thiết để truy cập nó bằng biến tĩnh, Chúng ta có thể viết "chuỗi cuối cùng riêng tư JDBC_PASSWORD =" password ";" thay vì sử dụng biến tĩnh cho chuỗi mật khẩu này.
chaitanya

48
@chaitanya Đó là một hằng số. Tại sao bạn muốn có một bản sao của biến cho mỗi phiên bản của lớp bằng cách làm cho nó không tĩnh?
Jesper

16
static là biến cấp độ lớp, là biến phổ biến và chỉ tồn tại một bản sao cho tất cả các phiên bản của lớp đó. Các quy tắc được áp dụng cho dù đó là tư nhân hoặc công cộng. private chỉ nói rằng tôi không muốn thế giới bên ngoài làm hỏng giá trị biến của tôi (đối với các thống kê không phải là cuối cùng). Nếu một tĩnh là cuối cùng thì không có hại trong việc biến nó thành công khai, vì không ai có thể thay đổi giá trị của nó.
dùng1923551

94

Các biến tĩnh có một giá trị duy nhất cho tất cả các thể hiện của một lớp.

Nếu bạn định làm một cái gì đó như:

public class Person
{
    private static int numberOfEyes;
    private String name;
}

và sau đó bạn muốn thay đổi tên của bạn, điều đó là tốt, tên của tôi vẫn giữ nguyên. Tuy nhiên, nếu bạn muốn thay đổi nó để bạn có 17 mắt thì mọi người trên thế giới cũng sẽ có 17 mắt.


3
Điều này không áp dụng cho các biến tĩnh riêng trừ khi bạn cũng viết các phương thức truy cập cho biến riêng vì chúng không thể được truy cập từ bên ngoài lớp.
Ganesh Krishnan

2
Không đúng @GaneshKrishnan, bất kỳ trường hợp nào của lớp đều có quyền truy cập vào cả hai biến. Đương nhiên, bạn có thể mong đợi rằng tác giả của lớp sẽ không làm điều gì ngớ ngẩn. Ngoài ra, với sự phản ánh và JNI, tất cả các cược đã tắt.
TofuBeer

46

Các biến tĩnh riêng rất hữu ích theo cùng một cách mà các biến thể hiện riêng tư rất hữu ích: chúng lưu trữ trạng thái chỉ được truy cập bằng mã trong cùng một lớp. Khả năng truy cập (riêng tư / công khai / v.v.) và bản chất / tĩnh của biến là các khái niệm hoàn toàn trực giao.

Tôi sẽ tránh nghĩ về các biến tĩnh được chia sẻ giữa "tất cả các trường hợp" của lớp - điều đó cho thấy phải có ít nhất một trường hợp để trạng thái có mặt. Không - một biến tĩnh được liên kết với chính loại thay vì bất kỳ trường hợp nào của loại.

Vì vậy, bất cứ khi nào bạn muốn một số trạng thái được liên kết với loại chứ không phải bất kỳ trường hợp cụ thể nào và bạn muốn giữ trạng thái đó ở chế độ riêng tư (ví dụ, có thể cho phép truy cập được kiểm soát thông qua các thuộc tính), có nghĩa là có một biến tĩnh riêng.

Bên cạnh đó, tôi thực sự khuyên bạn nên loại biến duy nhất mà bạn đặt công khai (hoặc thậm chí không riêng tư) là hằng số - biến cuối cùng tĩnh của loại không thay đổi. Mọi thứ khác phải riêng tư vì mục đích tách biệt API và triển khai (trong số những thứ khác).


Bạn có thể giải thích thêm một chút về sự khác biệt của truy cập biến tĩnh riêng tư và riêng tư không tĩnh trong một lớp không?
Dharmendra

1
@Dharmendra: Tôi không hiểu ý bạn là gì. Phần riêng tư không liên quan - chính xác điều gì làm bạn bối rối về sự khác biệt giữa các biến tĩnh và biến thể hiện?
Jon Skeet

Sự khác biệt về khả năng truy cập khi chúng ta sử dụng biến tĩnh và không tĩnh trong lớp đơn nơi chúng được khai báo là gì?
Dharmendra

2
@YogGuru: Tôi không thấy sự liên quan của câu hỏi. Đặt nó ở chế độ riêng tư nếu bạn muốn nó ở chế độ riêng tư và tĩnh nếu bạn muốn nó ở trạng thái tĩnh. Chúng trực giao.
Jon Skeet

1
@rycillage: Không, hoàn toàn không. Một phương thức tĩnh có thể truy cập nó mà không có vấn đề.
Jon Skeet

11

Vâng, bạn đúng các biến tĩnh công khai được sử dụng mà không cần tạo một thể hiện của lớp nhưng các biến tĩnh riêng thì không. Sự khác biệt chính giữa chúng và nơi tôi sử dụng các biến tĩnh riêng là khi bạn cần sử dụng một biến trong hàm tĩnh. Đối với các hàm tĩnh, bạn chỉ có thể sử dụng các biến tĩnh, vì vậy bạn đặt chúng ở chế độ riêng tư để không truy cập chúng từ các lớp khác. Đó là trường hợp duy nhất tôi sử dụng static private cho.

Đây là một ví dụ:

Class test {
   public static String name = "AA";
   private static String age;

   public static void setAge(String yourAge) {
       //here if the age variable is not static you will get an error that you cannot access non static variables from static procedures so you have to make it static and private to not be accessed from other classes
       age = yourAge;
   }
}

3
Tôi nghĩ rằng tôi thích câu trả lời này nhất. +1. Lần duy nhất có ý nghĩa khi sử dụng tĩnh trong một biến riêng là nếu một phương thức tĩnh được truy cập vào nó.
Mukus

Trong trường hợp đặt cho lớp một tên thích hợp, bạn thực sự không thể nói nếu đây là trường hợp sử dụng hợp lệ. Giống như, nếu lớp được gọi Person, thì đó có thể là một lỗi, bởi vì bạn không thể có nhiều người ở độ tuổi khác nhau (nếu đó là trường hợp sử dụng dự định).
DanMan

Tôi đồng ý @Mukus. Đây có thể là câu trả lời thực sự duy nhất cho câu hỏi này. Tôi nghĩ OP đã hiểu tĩnh nhưng mọi người dường như muốn giải thích lại. Ông đang hỏi về một kịch bản cụ thể. Khả năng truy cập các biến trong các phương thức tĩnh là chức năng 'private static' thêm vào. Tôi cũng muốn thêm rằng nó cũng cho phép truy cập LỚP tĩnh vào các biến.
Pinkerton

1
Còn trí nhớ thì sao? Với tĩnh, bạn chỉ tạo một bản sao cho lớp thay vì bản sao cho mọi trường hợp. Và rõ ràng với một hằng số, bạn chỉ cần một bản sao cho lớp. Điều này có tiết kiệm bộ nhớ?
Pinkerton

1
Tôi nhìn nó Câu trả lời cho câu hỏi trước đây của tôi là: có, nó tiết kiệm bộ nhớ
Pinkerton

8

Chà, private staticcác biến có thể được sử dụng để chia sẻ dữ liệu qua các thể hiện của lớp đó. Mặc dù bạn đúng rằng chúng ta không thể truy cập các private staticbiến bằng cách sử dụng các cấu trúc như ClassName.memberhoặc ClassInstance.membernhưng thành viên sẽ luôn hiển thị từ các phương thức của lớp đó hoặc các thể hiện của lớp đó. Vì vậy, trong các trường hợp có hiệu lực của lớp đó sẽ luôn có thể tham chiếu đến thành viên.


6

Việc sử dụng một biến lớp tĩnh riêng là gì?

Giả sử bạn có một lớp thư viện sách. Mỗi lần bạn tạo một Sách mới, bạn muốn gán cho nó một id duy nhất. Một cách đơn giản là bắt đầu từ 0 và tăng số id. Nhưng, làm thế nào để tất cả các cuốn sách khác biết số id được tạo cuối cùng? Đơn giản, lưu nó dưới dạng một biến tĩnh. Các khách hàng quen có cần biết rằng số id nội bộ thực tế là dành cho mỗi cuốn sách không? Không. Thông tin đó là riêng tư.

public class Book {
    private static int numBooks = 0;
    private int id;
    public String name;

    Book(String name) {
        id = numBooks++;
        this.name = name;
    }
}

Đây là một ví dụ giả định, nhưng tôi chắc chắn rằng bạn có thể dễ dàng nghĩ đến các trường hợp mà bạn muốn tất cả các thể hiện của lớp có quyền truy cập vào thông tin chung cần được giữ kín khỏi mọi người khác. Hoặc thậm chí nếu bạn không thể, đó là cách thực hành lập trình tốt để làm cho mọi thứ riêng tư nhất có thể. Điều gì sẽ xảy ra nếu bạn vô tình làm cho trường số đó thành công khai, mặc dù người dùng Sách không được phép làm bất cứ điều gì với nó. Sau đó, ai đó có thể thay đổi số lượng Sách mà không cần tạo Sách mới.

Rất lén lút!


6

Là khai báo một biến là private static varName;bất kỳ khác với khai báo một biến private varName;?

Vâng, cả hai đều khác nhau. Và cái đầu tiên được gọi class variablebởi vì nó giữ giá trị duy nhất cho điều đó classtrong khi cái còn lại được gọi instance variablebởi vì nó có thể giữ giá trị khác nhau cho khác nhau instances(Objects). Cái đầu tiên chỉ được tạo một lần trong jvm và cái khác được tạo một lần cho mỗi thể hiện, tức là nếu bạn có 10 thể hiện thì bạn sẽ có 10 cái khác nhau private varName;trong jvm.

Có khai báo biến như staticcho nó các thuộc tính đặc biệt khác không?

Có, các biến tĩnh nhận được một số thuộc tính khác với các biến thể hiện bình thường. Tôi đã đề cập vài cái rồi và chúng ta hãy xem một số ở đây: class variables(các biến thể hiện được khai báo là tĩnh) có thể được truy cập trực tiếp bằng cách sử dụng tên lớp như thế nào ClassName.varName. Và bất kỳ đối tượng nào của lớp đó đều có thể truy cập và sửa đổi giá trị của nó không giống như các biến thể hiện chỉ được truy cập bởi các đối tượng tương ứng. Các biến lớp có thể được sử dụng trong các phương thức tĩnh.

Việc sử dụng một private static variabletrong Java là gì?

Về mặt logic, private static variablekhông khác gì so với public static variablecái đầu tiên giúp bạn kiểm soát nhiều hơn. IMO, bạn có thể thay thế public static variabletheo nghĩa đen bằng private static variablesự trợ giúp của các public staticphương thức getter và setter.

Một lĩnh vực được sử dụng rộng rãi private static variablelà triển khai Singletonmẫu đơn giản trong đó bạn sẽ chỉ có một thể hiện duy nhất của lớp đó trên toàn thế giới. Ở đây staticđịnh danh đóng vai trò quan trọng để làm cho cá thể đó có thể truy cập được bởi thế giới bên ngoài (Tất nhiên phương thức getter tĩnh công khai cũng đóng vai trò chính).

public class Singleton {
    private static Singleton singletonInstance = new Singleton();

    private Singleton(){}

    public static Singleton getInstance(){
        return Singleton.singletonInstance;
    }
}

4

Từ khóa riêng sẽ sử dụng cho truy cập biến trong lớp và giữ tĩnh theo nghĩa chúng ta có thể truy cập biến trong phương thức tĩnh nhưng biến tham chiếu không thể truy cập trong phương thức tĩnh.


3

Một góc nhìn khác:

  1. Một lớp và thể hiện của nó là hai thứ khác nhau trong thời gian chạy. Một thông tin lớp được "chia sẻ" bởi tất cả các thể hiện của lớp đó.
  2. Các biến lớp không tĩnh thuộc về các thể hiện và biến tĩnh thuộc về lớp.
  3. Giống như một biến đối tượng có thể là riêng tư hoặc công khai, các biến tĩnh cũng có thể là riêng tư hoặc công khai.

1

Khi trong một phương thức tĩnh bạn sử dụng một biến, biến đó phải là tĩnh như một ví dụ:

private static int a=0;  
public static void testMethod() {  
        a=1;  
}

3
Chà, trừ khi phương thức của bạn được đưa ra một tham chiếu đến một thể hiện của lớp tất nhiên.
Jon Skeet

1

Biến tĩnh là những biến chung cho tất cả các thể hiện của một lớp..nếu một thể hiện thay đổi nó .. thì giá trị của biến tĩnh sẽ được cập nhật cho tất cả các thể hiện khác


1

Đối với một số người, điều này có ý nghĩa hơn nếu họ thấy nó bằng một vài ngôn ngữ khác nhau vì vậy tôi đã viết một ví dụ bằng Java và PHP trên trang của tôi nơi tôi giải thích một số sửa đổi này. Bạn có thể nghĩ về điều này không chính xác.

Bạn nên xem ví dụ của tôi nếu nó không có ý nghĩa dưới đây. Truy cập tại đây http://www.siteconsortium.com/h/D0000D.php

Điểm mấu chốt là nó khá chính xác với những gì nó nói. Đó là một biến thành viên tĩnh là riêng tư. Ví dụ: nếu bạn muốn tạo một đối tượng Singleton tại sao bạn muốn đặt biến SingletonExample.instance thành công khai. Nếu bạn đã làm một người đang sử dụng lớp có thể dễ dàng ghi đè lên giá trị.

Đó là tất cả.

    lớp công khai SingletonExample {
      cá nhân SingletonExample tĩnh = null;
      int int int value = 0;
      riêng tư SingletonExample () {
        ++ này. Giá trị;
      }
      công khai SingletonExample getInstance () {
        if (dụ! = null)
        ví dụ trả lại;
        đã đồng bộ hóa (SingletonExample. class) {
        dụ = SingletonExample ();
        ví dụ trả lại;
        }
      }
      công khai void printValue () {
        System.out.print (this.value);
      }

      public static void main (String [] args) {
        Ví dụ SingletonExample = getInstance ();
        dụ.printValue ();
        dụ = getInstance ();
        dụ.printValue ();
         }
    }


1

Nếu bạn sử dụng các biến tĩnh riêng trong lớp, các lớp Tĩnh trong lớp có thể tiếp cận các biến của bạn. Điều này là hoàn toàn tốt cho bảo mật bối cảnh.


0

Nếu một biến được định nghĩa là tĩnh công khai, nó có thể được truy cập thông qua tên lớp từ bất kỳ lớp nào.

Thông thường các hàm được định nghĩa là tĩnh công khai có thể được truy cập chỉ bằng cách gọi tên lớp thực hiện.

Một ví dụ rất hay về nó là sleep()phương thức trong lớp Thread

Thread.sleep(2500);

Nếu một biến được định nghĩa là private private thì nó chỉ có thể được truy cập trong lớp đó để không cần tên lớp hoặc bạn vẫn có thể sử dụng tên lớp (tùy theo bạn). Sự khác biệt giữa var_name riêng và var_name tĩnh riêng là các biến tĩnh riêng chỉ có thể được truy cập bằng các phương thức tĩnh của lớp trong khi các biến riêng có thể được truy cập bởi bất kỳ phương thức nào của lớp đó (ngoại trừ các phương thức tĩnh)

Một ví dụ rất hay về nó là trong khi xác định các kết nối cơ sở dữ liệu hoặc hằng yêu cầu khai báo biến là tĩnh riêng.

Một ví dụ phổ biến khác là

private static int numberOfCars=10;

public static int returnNumber(){

return numberOfCars;

}

0

Tôi mới sử dụng Java, nhưng một cách tôi sử dụng các biến tĩnh, như tôi giả sử nhiều người làm, là đếm số lượng phiên bản của lớp. ví dụ:

public Class Company {
    private static int numCompanies;

    public static int getNumCompanies(){
        return numCompanies;
    }
}

Sau đó, bạn có thể sysout:

Company.getNumCompanies();

Bạn cũng có thể có quyền truy cập vào numCompiances từ mỗi phiên bản của lớp (mà tôi hoàn toàn không hiểu), nhưng nó sẽ không theo "cách tĩnh". Tôi không biết đây có phải là cách thực hành tốt nhất hay không, nhưng nó có ý nghĩa với tôi.


0

*) Nếu một biến được khai báo là riêng tư thì nó không hiển thị bên ngoài lớp. Điều này được gọi là datahiding.

*) Nếu một biến được khai báo là tĩnh thì giá trị của biến là giống nhau cho tất cả các trường hợp và chúng ta không cần tạo một đối tượng để gọi biến đó. Chúng ta có thể gọi biến đó bằng cách đơn giản

tên lớp.variablename;


0

biến tĩnh riêng cũng sẽ được chia sẻ trong lớp con. Nếu bạn thay đổi trong một lớp con và lớp con khác sẽ nhận được giá trị thay đổi, trong trường hợp đó, nó có thể không như bạn mong đợi.

public class PrivateStatic {

private static int var = 10;
public void setVar(int newVal) {
    var = newVal;
}

public int getVar() {
    return var;
}

public static void main(String... args) {
    PrivateStatic p1 = new Sub1();
    System.out.println(PrivateStatic.var);
    p1.setVar(200);

    PrivateStatic p2 = new Sub2();
    System.out.println(p2.getVar());
}
}


class Sub1 extends PrivateStatic {

}

class Sub2 extends PrivateStatic {
}

0

ThreadLocalcác biến thường được thực hiện như private static. Theo cách này, chúng không bị ràng buộc với lớp và mỗi luồng có tham chiếu riêng đến đối tượng "ThreadLocal" của riêng nó.


3
Tôi không hiểu câu trả lời này. Ý anh là gì?
H.Rabiee

-1

Trong ví dụ sau, eyeđược PersonB thay đổi, trong khi legvẫn giữ nguyên. Điều này là do một biến riêng tạo một bản sao của chính nó cho phương thức, sao cho giá trị ban đầu của nó giữ nguyên; trong khi một giá trị tĩnh riêng chỉ có một bản sao cho tất cả các phương thức để chia sẻ, vì vậy việc chỉnh sửa giá trị của nó sẽ thay đổi giá trị ban đầu của nó.

public class test {
private static int eye=2;
private int leg=3;

public test (int eyes, int legs){
    eye = eyes;
    leg=leg;
}

public test (){
}

public void print(){
    System.out.println(eye);
    System.out.println(leg);
}

public static void main(String[] args){
    test PersonA = new test();      
    test PersonB = new test(14,8);
    PersonA.print();    
}

}

> 14 3

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.