Tại sao tôi không thể có chuỗi const tĩnh tĩnh S = công cụ "; trong Lớp của tôi?


321

Khi cố gắng biên dịch lớp tôi gặp lỗi:

Các hằng số 'NamespaceName.ClassName.CONST_NAME'không thể được đánh dấu tĩnh.

tại dòng:

public static const string CONST_NAME = "blah";

Tôi có thể làm điều này mọi lúc trong Java. Tôi đang làm gì sai? Và tại sao nó không cho phép tôi làm điều này?

Câu trả lời:


583

Một constđối tượng luôn static.


2
const làm cho biến không đổi và không thể thay đổi.
Samuel

6
@jinguy: const vốn có nghĩa là tĩnh - nếu bạn có bất kỳ const nào, thì nó đã tĩnh và do đó không cần phải được chỉ định.
John Rudy

8
@jjnguy: Tại sao? readonly thực sự linh hoạt hơn so với biến cuối cùng của Java - bạn có thể đặt nó bao nhiêu lần tùy thích trong hàm tạo, nhưng không phải ở nơi khác. Điều đó có thể rất tiện dụng.
Jon Skeet

67
Các hằng số được nội tuyến tại thời gian biên dịch và không có trong đối tượng kiểu tĩnh khi chạy. Statics không được nội tuyến và sống bên trong đối tượng loại. Tôi thêm điều này chỉ vì không ai đề cập đến sự khác biệt ...

3
Chúng vẫn hiện diện tại thời điểm thực hiện - ví dụ, bạn có thể nhận được chúng bằng phản xạ (với GetField).
Jon Skeet


32

Một thành viên const được coi là tĩnh bởi trình biên dịch, cũng như ngụ ý ngữ nghĩa giá trị không đổi, có nghĩa là các tham chiếu đến hằng số có thể được biên dịch thành mã sử dụng làm giá trị của thành viên hằng, thay vì tham chiếu đến thành viên.

Nói cách khác, một thành viên const chứa giá trị 10, có thể được biên dịch thành mã sử dụng nó làm số 10, thay vì tham chiếu đến thành viên const.

Điều này khác với trường chỉ đọc tĩnh, sẽ luôn được biên dịch dưới dạng tham chiếu đến trường.

Lưu ý, đây là tiền JIT. Khi JIT'ter hoạt động, nó có thể biên dịch cả hai thứ này thành mã đích làm giá trị.


Điểm rất quan trọng, mã được biên dịch giả định giá trị không đổi sẽ không thay đổi trong phiên bản tương lai.
PJTraill

6

C # constlà chính xác giống như của Java final, ngoại trừ nó hoàn toàn luôn luôn static. Theo tôi, không thực sự cần thiết cho một constbiến là không static, nhưng nếu bạn cần truy cập vào một constbiến không phải static, bạn có thể làm:

class MyClass
{    
    private const int myLowercase_Private_Const_Int = 0;
    public const int MyUppercase_Public_Const_Int = 0;

    /*        
      You can have the `private const int` lowercase 
      and the `public int` Uppercase:
    */
    public int MyLowercase_Private_Const_Int
    {
        get
        {
            return MyClass.myLowercase_Private_Const_Int;
        }
    }  

    /*
      Or you can have the `public const int` uppercase 
      and the `public int` slighly altered
      (i.e. an underscore preceding the name):
    */
    public int _MyUppercase_Public_Const_Int
    {
        get
        {
            return MyClass.MyUppercase_Public_Const_Int;
        }
    } 

    /*
      Or you can have the `public const int` uppercase 
      and get the `public int` with a 'Get' method:
    */
    public int Get_MyUppercase_Public_Const_Int()
    {
        return MyClass.MyUppercase_Public_Const_Int;
    }    
}

Chà, bây giờ tôi nhận ra câu hỏi này đã được hỏi 4 năm trước, nhưng vì tôi đã dành khoảng 2 giờ làm việc, bao gồm thử tất cả các cách trả lời và định dạng mã khác nhau, vào câu trả lời này, tôi vẫn đăng nó. :)

Nhưng, đối với hồ sơ, tôi vẫn cảm thấy hơi ngớ ngẩn.


4
Theo như tôi có thể nói, Java finalhoạt động chính xác như C # readonlyvà hoàn toàn không giống như vậy const.
Ben Voigt

@jjnguy Cảm ơn bạn đã chỉnh sửa; Tôi thực sự không biết tại sao tôi chọn từ ngữ gốc đó.
Meowmaritus

6

Từ MSDN: http://msdn.microsoft.com/en-us/l Library / acdd6hb7.aspx

... Ngoài ra, trong khi trường const là hằng số thời gian biên dịch , trường chỉ đọc có thể được sử dụng cho hằng số thời gian chạy ...

Vì vậy, sử dụng tĩnh trong các trường const cũng giống như cố gắng tạo một tĩnh (với #define) được xác định trong C / C ++ ... Vì nó được thay thế bằng giá trị của nó trong thời gian biên dịch tất nhiên, nó được khởi tạo một lần cho tất cả các trường hợp (= static) .


2

const tương tự như tĩnh, chúng ta có thể truy cập cả hai biến với tên lớp nhưng diff là biến tĩnh có thể được sửa đổi và const không thể.

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.