วิธีระบุค่าให้กับหมายเหตุประกอบจาก Constant java


146

ฉันคิดว่าสิ่งนี้อาจเป็นไปไม่ได้ใน Java เพราะคำอธิบายประกอบและพารามิเตอร์ของมันได้รับการแก้ไขในเวลารวบรวม ฉันมีส่วนต่อประสานดังนี้

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

และอีกชั้นหนึ่งว่า

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

ฉันทำเครื่องหมายหลายคลาสด้วยคำอธิบายประกอบและฉันต้องการทราบว่าฉันสามารถหลีกเลี่ยงการระบุสตริงในคำอธิบายประกอบทุกครั้งที่ฉันต้องการใช้แทน

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

อย่างไรก็ตามสิ่งนี้ให้ข้อผิดพลาดในการคอมไพล์เช่นค่าคำอธิบายประกอบควรเป็น initializer ของอาร์เรย์เป็นต้นมีใครรู้ว่าฉันสามารถใช้ค่าคงที่แบบสตริงหรือค่าคงที่สตริง [] เพื่อให้ค่าของคำอธิบายประกอบได้หรือไม่

คำตอบ:


127

ค่าคงที่ของคอมไพล์สามารถเป็นแบบพื้นฐานและสตริงเท่านั้น :

15.28 นิพจน์คงที่

นิพจน์ค่าคงที่เวลาคอมไพล์คือนิพจน์ที่แสดงถึงค่าชนิดดั้งเดิมหรือสตริงที่ไม่เสร็จสมบูรณ์อย่างฉับพลันและประกอบขึ้นโดยใช้สิ่งต่อไปนี้เท่านั้น:

  • ตัวอักษรชนิดดั้งเดิมและตัวอักษรประเภท String
  • ปลดเปลื้องกับประเภทดั้งเดิมและปลดเปลื้องเพื่อพิมพ์ String
  • [... ] โอเปอเรเตอร์ [... ]
  • นิพจน์วงเล็บที่มีนิพจน์ที่มีอยู่คือนิพจน์คงที่
  • ชื่อแบบง่ายที่อ้างถึงตัวแปรคงที่
  • ชื่อที่ผ่านการรับรองของแบบฟอร์มTypeName ตัวบ่งชี้ที่อ้างถึงตัวแปรคงที่

ที่จริงแล้วใน java ไม่มีวิธีป้องกันรายการในอาเรย์ ที่ runtime ใครบางคนสามารถทำได้ตลอดเวลาFieldValues.FIELD1[0]="value3"ดังนั้น array จึงไม่สามารถคงที่ได้ถ้าเรามองลึกลงไป


14
Enums ด้วย! :) :)
TacB0sS

1
@ TacB0sS, enums ไม่ใช่นิพจน์คงที่
jaco0646

ดี ... บางทีคุณควรให้มันไปและแจ้งให้เรารู้ว่า ... ฉันจะใช้พวกเขาตลอดเวลา :)
TacB0sS

4
สเป็คที่เกี่ยวข้องมากขึ้นอยู่ภายใต้คำอธิบายประกอบ นอกจากการแสดงออกคงค่าคำอธิบายประกอบสามารถเป็นอาร์เรย์ initializer , ระดับตัวอักษรหรือenum คงที่
jaco0646

3
@ TacB0sS คุณสามารถใช้enumในบันทึกย่อได้ แต่ไม่ได้รวบรวมเวลาคงที่ ความแตกต่างจะชัดเจนเมื่อคุณเขียนstatic final EnumType VARIABLE = EnumType.ENUM_CONSTANT;และพยายามใช้VARIABLEในการเพิ่มความคิดเห็น มันจะไม่ทำงาน คุณสามารถใช้EnumType.ENUM_CONSTANTซึ่งไม่ได้เป็นนิพจน์คงที่เท่านั้น แต่ได้รับอนุญาตเป็นพิเศษในคำอธิบายประกอบ (และswitchคำสั่ง)
Holger

37

คุณสามารถใช้ค่าคงที่ (เช่นตัวแปรสุดท้ายและคงที่) เป็นพารามิเตอร์สำหรับคำอธิบายประกอบ เป็นตัวอย่างรวดเร็วฉันใช้สิ่งนี้ค่อนข้างบ่อย:

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);
    }
}

โปรดทราบว่าเป็นไปได้ที่จะส่งTEST_TIMEOUTค่าคงที่ตรงไปยังคำอธิบายประกอบ

โดยส่วนตัวแล้วฉันจำไม่ได้ว่าเคยลองทำกับอาร์เรย์ดังนั้นคุณอาจพบปัญหาบางอย่างที่มีความแตกต่างกันเล็กน้อยในการแสดงอาร์เรย์เป็นพารามิเตอร์คำอธิบายประกอบเมื่อเทียบกับตัวแปร Java หรือไม่ แต่สำหรับส่วนอื่น ๆ ของคำถามของคุณคุณสามารถใช้สตริงคงที่ได้โดยไม่มีปัญหา

แก้ไข: ฉันได้พยายามเพียงแค่นี้กับอาร์เรย์สตริงและไม่ได้ทำงานเป็นปัญหาที่คุณกล่าวถึง - แต่คอมไพเลอร์ไม่บอกฉันว่า "ค่าแอตทริบิวต์จะต้องคงที่" public static final String[]แม้จะมีอาร์เรย์ที่ถูกกำหนดให้เป็น บางทีมันอาจจะไม่ชอบความจริงที่ว่าอาร์เรย์ไม่แน่นอน อืม ...


1
โชคดีสำหรับฉัน! โอ้ใช่ฉันสามารถผ่านสตริง / หมายเลข แต่ไม่ใช่อาร์เรย์ ผมจะใช้เวลาอีกเล็กน้อยเกี่ยวกับเรื่องนี้และถ้าไม่มีอะไรทำงานออกจะยอมรับคำตอบ :)
คาน Ekanath

ใช่ฉันเดาว่าความไม่แน่นอนของอาร์เรย์ FIELD1 เป็นปัญหาที่นี่ คุณได้รับอนุญาตให้ประกาศอาร์เรย์ด้วย array initializer เนื่องจากไม่มีสิ่งใดที่สามารถเข้าถึงอาร์เรย์นั้นได้ดังนั้นจึงไม่สามารถเปลี่ยนแปลงได้ในภายหลัง
ColinD

นี่เป็นการแก้ปัญหาของฉัน เพียงต้องการแชร์ค่าคงที่สตริงระหว่างคำอธิบายประกอบและรหัส ขอบคุณ!
simon

1
ตัวแปรสแตติกสุดท้ายไม่ใช่ข้อกำหนดเบื้องต้นเท่านั้น หากคุณพยายามคำนวณตัวแปรแบบไดนามิกคุณจะได้รับข้อความแสดงข้อผิดพลาดเดียวกัน
Wolfgang Fahl

11

คุณไม่ได้จัดส่งอาร์เรย์ในตัวอย่างของคุณ คอมไพล์ดังต่อไปนี้ปรับ:

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
มันจะถูกจัดให้กับอาร์เรย์ในตัวอย่างไม่ใช่เพียงหนึ่งที่สร้างขึ้นโดยตรงในการประกาศคำอธิบายประกอบ
ColinD

7

มีใครรู้บ้างว่าฉันจะใช้ค่าคงที่สตริงหรือค่าคงที่สตริง [] เพื่อส่งค่าคำอธิบายประกอบได้อย่างไร

น่าเสียดายที่คุณไม่สามารถทำได้ด้วยอาร์เรย์ ด้วยตัวแปรที่ไม่ใช่อาร์เรย์ค่าต้องเป็นสแตติกสุดท้าย


5

ฉันคิดว่าสิ่งนี้อาจเป็นไปไม่ได้ใน Java เพราะคำอธิบายประกอบและพารามิเตอร์ของมันได้รับการแก้ไขในเวลารวบรวม

ด้วย Seam 2 http://seamframework.org/คุณสามารถแก้ไขพารามิเตอร์คำอธิบายประกอบขณะใช้งานจริงด้วยภาษานิพจน์ในเครื่องหมายคำพูดคู่

ใน Seam 3 http://seamframework.org/Seam3/Solderคุณลักษณะนี้คือโมดูล Seam Solder


3
ไม่คุณไม่ได้แก้ไขพารามิเตอร์ตอนรันไทม์ พารามิเตอร์ถูกแก้ไขในเวลาคอมไพล์ ที่พวกเขาเคยทำบางสิ่งบางอย่างที่รันไทม์ไม่มีอะไรจะทำเมื่อตั้งค่า
คดีกองทุนของโมนิกา

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.