Cách cung cấp giá trị cho chú thích từ Constant java


146

Tôi nghĩ điều này có thể không khả thi trong Java vì chú thích và các tham số của nó được giải quyết tại thời điểm biên dịch. Tôi có một giao diện như sau,

public interface FieldValues {
   String[] FIELD1 = new String[]{"value1", "value2"};
}

và một lớp khác như,

@SomeAnnotation(locations = {"value1", "value2"})
public class MyClass {
   ....
}

Tôi đánh dấu nhiều lớp bằng chú thích và tôi muốn biết liệu tôi có thể tránh chỉ định các chuỗi trong mỗi chú thích mà tôi muốn sử dụng không

@SomeAnnotation(locations = FieldValues.FIELD1)
public class MyClass {
   ....
}

Tuy nhiên, điều này mang lại các lỗi biên dịch như giá trị chú thích nên là một trình khởi tạo mảng, v.v. Có ai biết làm thế nào tôi có thể sử dụng hằng Chuỗi hay hằng [] để cung cấp giá trị cho chú thích không?

Câu trả lời:


126

Các hằng số biên dịch chỉ có thể là nguyên hàm và Chuỗi :

15,28. Biểu thức không đổi

Biểu thức hằng số thời gian biên dịch là biểu thức biểu thị một giá trị của kiểu nguyên thủy hoặc Chuỗi không hoàn thành đột ngột và được cấu thành chỉ bằng cách sử dụng sau:

  • Văn học của loại nguyên thủy và văn học loại String
  • Chuyển sang loại nguyên thủy và phôi để gõ String
  • [...] Toán tử [...]
  • Các biểu thức được ngoặc đơn có biểu thức chứa là một biểu thức không đổi.
  • Tên đơn giản đề cập đến các biến không đổi.
  • Tên đủ điều kiện của mẫu TypeName . Định danh tham chiếu đến các biến không đổi.

Trên thực tế trong java không có cách nào để bảo vệ các mục trong một mảng. Trong thời gian chạy ai đó luôn có thể làm FieldValues.FIELD1[0]="value3", do đó mảng không thể thực sự ổn định nếu chúng ta nhìn sâu hơn.


14
Enums quá! :) :)
TacB0sS

1
@ TacB0sS, enum không phải là biểu thức không đổi.
jaco0646

Chà ... có lẽ bạn nên thử và cho tôi biết ... Tôi sử dụng chúng mọi lúc :)
TacB0sS

4
Một thông số kỹ thuật phù hợp hơn là theo Chú thích . Ngoài một biểu thức hằng, một giá trị chú thích có thể là một bộ khởi tạo mảng , hằng số lớp hoặc hằng số enum .
jaco0646

3
@ TacB0sS bạn có thể sử dụng enumtrong annotatios, nhưng chúng không phải là hằng số thời gian biên dịch. Sự khác biệt trở nên rõ ràng khi bạn viết static final EnumType VARIABLE = EnumType.ENUM_CONSTANT;và cố gắng sử dụng VARIABLEtrong một chú thích; nó sẽ không hoạt động. Bạn chỉ có thể sử dụngEnumType.ENUM_CONSTANT đó không phải là biểu thức hằng, nhưng được phép cụ thể trong chú thích (và switchcâu lệnh).
Holger

37

Bạn có thể sử dụng hằng số (tức là biến tĩnh, biến cuối) làm tham số cho chú thích. Để làm ví dụ nhanh, tôi sử dụng một cái gì đó như thế này khá thường xuyên:

import org.junit.Test;
import static org.junit.Assert.*;

public class MyTestClass
{
    private static final int TEST_TIMEOUT = 60000; // one minute per test

    @Test(timeout=TEST_TIMEOUT)
    public void testJDK()
    {
        assertTrue("Something is very wrong", Boolean.TRUE);
    }
}

Lưu ý rằng có thể chuyển TEST_TIMEOUThằng số thẳng vào chú thích.

Chính thức, tôi không nhớ đã từng thử điều này với một mảng, vì vậy bạn có thể gặp phải một số vấn đề với sự khác biệt nhỏ về cách các mảng được biểu diễn dưới dạng tham số chú thích so với các biến Java? Nhưng đối với phần khác của câu hỏi của bạn, bạn chắc chắn có thể sử dụng Chuỗi không đổi mà không gặp vấn đề gì.

EDIT: Tôi vừa thử điều này với mảng String và không gặp phải vấn đề bạn đã đề cập - tuy nhiên trình biên dịch đã nói với tôi rằng "giá trị thuộc tính phải không đổi" mặc dù mảng được định nghĩa là public static final String[]. Có lẽ nó không giống như thực tế là mảng có thể thay đổi? Hừm ...


1
May mắn cho tôi! Oh yah Tôi đã có thể vượt qua Chuỗi / Số nhưng không phải là mảng. Tôi sẽ dành thêm một chút thời gian cho việc này và nếu không có gì hiệu quả sẽ chấp nhận câu trả lời :)
Kannan Ekanath

Vâng, tôi đoán là khả năng biến đổi của mảng FIELD1 là vấn đề ở đây. Bạn được phép khai báo mảng bằng trình khởi tạo mảng vì không có gì khác có thể có quyền truy cập vào mảng đó và vì vậy nó không thể thay đổi sau đó.
ColinD

Điều này giải quyết vấn đề của tôi. Chỉ cần chia sẻ hằng chuỗi giữa chú thích và mã. Cảm ơn!
simon

1
biến cuối cùng tĩnh không phải là điều kiện tiên quyết duy nhất. Nếu bạn cố gắng tự động calc biến, bạn sẽ nhận được thông báo lỗi tương tự.
Wolfgang Fahl

11

Bạn không cung cấp cho nó một mảng trong ví dụ của bạn. Các biên dịch sau đây tốt:

public @interface SampleAnnotation {
    String[] sampleValues();
}

public class Values {
    public static final String val0 = "A";
    public static final String val1 = "B";

    @SampleAnnotation(sampleValues={ val0, val1 })
    public void foo() {
    }
}

4
Nó đang được cung cấp với một mảng trong ví dụ, không phải là một mảng được tạo trực tiếp trong khai báo chú thích.
ColinD

7

Có ai biết làm thế nào tôi có thể sử dụng hằng chuỗi hay hằng chuỗi [] để cung cấp giá trị cho chú thích không?

Thật không may, bạn không thể làm điều này với mảng. Với các biến không phải là mảng, giá trị phải là tĩnh cuối cùng.


5

Tôi nghĩ điều này có thể không khả thi trong Java vì chú thích và các tham số của nó được giải quyết tại thời điểm biên dịch.

Với Seam 2 http://seamframework.org/ bạn có thể giải quyết các tham số chú thích trong thời gian chạy, với ngôn ngữ biểu thức bên trong dấu ngoặc kép.

Trong Seam 3 http://seamframework.org/Seam3/Solder , tính năng này là mô-đun Seam Solder


3
Không, bạn đã không giải quyết các tham số trong thời gian chạy. Các tham số đã được giải quyết tại thời gian biên dịch. Rằng họ sau đó được sử dụng để làm một cái gì đó trong thời gian chạy thực sự không có gì để làm khi giá trị của chúng được đặt.
Vụ kiện của Quỹ Monica

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.