एक निरंतर जावा से एक एनोटेशन के लिए मूल्य की आपूर्ति कैसे करें


146

मैं सोच रहा हूं कि जावा में यह संभव नहीं हो सकता क्योंकि एनोटेशन और इसके मापदंडों का संकलन समय पर किया जाता है। मेरा एक इंटरफ़ेस निम्नानुसार है,

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

और एक अन्य वर्ग के रूप में,

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

मैं एनोटेशन के साथ कई वर्गों को चिह्नित करता हूं और मैं जानना चाहता हूं कि क्या मैं हर एनोटेशन में तारों को निर्दिष्ट करने से बच सकता हूं जो मैं उपयोग करना पसंद करूंगा

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

हालाँकि यह संकलन त्रुटियों देता है जैसे एनोटेशन वैल्यू एक ऐरर इनिशियलाइज़र होना चाहिए आदि।

जवाबों:


127

संकलित स्थिरांक केवल आदिम और स्ट्रिंग्स हो सकते हैं :

15.28। लगातार अभिव्यक्तियाँ

एक संकलन-समय स्थिर अभिव्यक्ति एक अभिव्यक्ति है जो आदिम प्रकार या एक स्ट्रिंग के मूल्य को दर्शाती है जो अचानक पूरी नहीं होती है और केवल निम्नलिखित का उपयोग करके बनाई गई है:

  • आदिम प्रकार के साहित्य और प्रकार के शाब्दिक String
  • आदिम प्रकारों को कास्ट करता है और टाइप करने के लिए कास्ट करता है String
  • [...] ऑपरेटरों [...]
  • कोष्ठबद्ध अभिव्यक्ति जिनकी निहित अभिव्यक्ति एक स्थिर अभिव्यक्ति है।
  • सरल नाम जो निरंतर चर को संदर्भित करते हैं।
  • टाइप नाम के योग्य नाम । पहचानकर्ता जो निरंतर चर का संदर्भ देता है।

वास्तव में जावा में एक सरणी में वस्तुओं की रक्षा करने का कोई तरीका नहीं है। रनटाइम के दौरान कोई हमेशा कर सकता है FieldValues.FIELD1[0]="value3", इसलिए यदि हम गहराई से देखें तो सरणी वास्तव में स्थिर नहीं हो सकती है।


14
एनम भी! :) :)
TacB0sS

1
@ TacB0sS, एनम लगातार अभिव्यक्ति नहीं हैं।
jaco0646

अच्छा ... शायद आप इसे जाने दें और मुझे बताएं ... मैं हर समय उनका उपयोग करता हूं :)
TacB0sS

4
एनोटेशन के तहत एक अधिक प्रासंगिक युक्ति है । एक स्थिर अभिव्यक्ति के अलावा, एक एनोटेशन मान एक सरणी इनिशियलाइज़र , वर्ग शाब्दिक , या एनम स्थिर हो सकता है
jaco0646

3
@ TacB0sS आप एनोटोटियोज enumमें उपयोग कर सकते हैं , लेकिन वे संकलन-समय स्थिर नहीं हैं। अंतर स्पष्ट हो जाता है जब आप लिखते हैं static final EnumType VARIABLE = EnumType.ENUM_CONSTANT;और VARIABLEएक एनोटेशन में उपयोग करने का प्रयास करते हैं ; यह काम नहीं करेगा। आप केवल उसी का उपयोग कर सकते हैं EnumType.ENUM_CONSTANTजो एक स्थिर अभिव्यक्ति नहीं है, लेकिन विशेष रूप से एनोटेशन (और switchकथन) में अनुमति दी गई है ।
होल्गर

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एनोटेशन में सीधे स्ट्रेट पास करना संभव है ।

ऑफहैंड, मुझे याद नहीं है कि कभी किसी सरणी के साथ यह करने की कोशिश की गई है, इसलिए आप कुछ मुद्दों में थोड़े अंतर के साथ चल रहे हो सकते हैं कि कैसे जावा वैरिएबल की तुलना में एनोटेशन मापदंडों के रूप में एरे को दर्शाया जाता है? लेकिन अपने प्रश्न के दूसरे भाग के रूप में, आप निश्चित रूप से बिना किसी समस्या के लगातार स्ट्रिंग का उपयोग कर सकते हैं।

संपादित करें: मैंने इसे केवल एक स्ट्रिंग सरणी के साथ आज़माया है, और आपके द्वारा बताई गई समस्या में नहीं चला - हालाँकि कंपाइलर ने मुझे बताया कि सरणी के रूप में परिभाषित होने के बावजूद "विशेषता मान स्थिर होना चाहिए" public static final String[]। शायद यह इस तथ्य को पसंद नहीं करता है कि सरणियाँ परस्पर हैं? हम्म ...


1
मेरे लिए कठिन भाग्य! ओह, मैं स्ट्रिंग्स / नंबरों को पास करने में सक्षम था, लेकिन सरणियाँ नहीं। मैं इस पर थोड़ा और समय
बिताऊंगा

हाँ, मेरा अनुमान यह होगा कि FIELD1 सरणी की परिवर्तनशीलता यहाँ मुद्दा है। आपको सरणी एनेलाइज़र के साथ ऐरे को घोषित करने की अनुमति है क्योंकि उस ऐरे में और कुछ नहीं हो सकता है और इसलिए इसे बाद में नहीं बदला जा सकता है।
कॉलिनड

इससे मेरी समस्या हल हो गई। बस एनोटेशन और कोड के बीच एक स्ट्रिंग स्थिर साझा करने की आवश्यकता है। धन्यवाद!
सिमोन

1
स्थैतिक अंतिम चर केवल पूर्वापेक्षा नहीं है। यदि आप वैरिएबल को वैसा ही करने का प्रयास करते हैं तो आपको वही त्रुटि संदेश मिलेगा।
वोल्फगैंग फाहल

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
यह उदाहरण में एक सरणी के साथ दिया जा रहा है, बस एक ऐसा नहीं है जो सीधे एनोटेशन घोषणा में बनाया गया है।
कॉलिनडी

7

क्या कोई जानता है कि मैं एक स्ट्रिंग स्थिरांक या स्ट्रिंग [] स्थिरांक का उपयोग कैसे कर सकता हूं एक एनोटेशन के लिए मूल्य की आपूर्ति करने के लिए?

दुर्भाग्य से, आप सरणियों के साथ ऐसा नहीं कर सकते। गैर-सरणी चर के साथ, मूल्य अंतिम स्थिर होना चाहिए।


5

मैं सोच रहा हूं कि जावा में यह संभव नहीं हो सकता क्योंकि एनोटेशन और इसके मापदंडों का संकलन समय पर किया जाता है।

सीम 2 के साथ http://seamframework.org/ आप रनटाइम पर एनोटेशन मापदंडों को हल करने में सक्षम थे, डबल उद्धरण के अंदर अभिव्यक्ति भाषा के साथ।

सीम 3 http://seamframework.org/Seam3/Solder में , यह सुविधा मॉड्यूल सीम सोल्डर है


3
नहीं, आपने रनटाइम पर मापदंडों को हल नहीं किया है। पैरामीटर को संकलन-समय पर हल किया गया था। तब वे रनटाइम के दौरान कुछ करने के लिए इस्तेमाल किए गए थे, जब उनके मूल्यों को सेट किया गया था, तो उनका वास्तव में कोई लेना-देना नहीं था।
निधि मोनिका का मुकदमा

1

आप एनम का उपयोग कर सकते हैं और एनोटेशन क्षेत्र में उस एनम को संदर्भित कर सकते हैं


1
आपको एक उदाहरण जोड़ना चाहिए।
m02ph3u5
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.