यहां कुछ समस्याएं हैं। आप या तो में विधि आवेषण रिसीवर के जावा प्रकार को जानना या विधि पर कक्षा को जानना जानना चाहते हैं। जावा जानकारी अधिक जानकारीपूर्ण है क्योंकि यह आपको सामान्य प्रकार भी प्रदान करती है, उदा। List<String>
जबकि तत्व केवल आपको कक्षा प्रदान करेंगे, उदा। List<E>
।
तत्व
हो रही वर्ग पद्धति पर शुरू हो जाती है का तत्व पाने के लिए आपको कर सकते हैं निम्नलिखित:
MethodInvocationTree node = ...;
Element method =
TreeInfo.symbol((JCTree)node.getMethodSelect());
TypeElement invokedClass = (TypeElement)method.getEnclosingElement();
कॉर्नर मामलों:
1. invoked क्लास रिसीवर प्रकार का एक सुपरक्लास हो सकता है। तो टुकड़ा चल new ArrayList<String>.equals(null)
पर AbstractList
बजाय ArrayList
, बराबरी के बाद वापस होगा() AbstractList
नहीं ArrayList
में कार्यान्वित किया जाता है।
2. सरणी आमंत्रणों को संभालने पर, उदा। new int[].clone()
, आप TypeElement
कक्षा Array
प्राप्त करेंगे।
वास्तविक प्रकार
हो रही प्रकार प्राप्त करने के लिए, वहाँ यह निर्धारित करने के लिए क्या रिसीवर प्रकार है के लिए कोई सीधा रास्ता है। अंदरूनी कक्षाओं के भीतर विधि आमंत्रण को संभालने में कुछ जटिलता है जहां रिसीवर स्पष्ट रूप से (उदा। OuterClass.this.toString()
के विपरीत) नहीं दिया गया है। यहां एक नमूना दिया गया है:
MethodInvocationTree node = ...;
TypeMirror receiver;
if (methodSel.getKind() == Tree.Kind.MEMBER_SELECT) {
ExpressionTree receiver = ((MemberSelectTree)methodSel).getExpression();
receiverType = ((JCTree)receiver).type;
} else if (methodSel.getKind() == Tree.Kind.IDENTIFIER) {
// need to resolve implicit this, which is described in
// JLS3 15.12.1 and 15.9.2
// A bit too much work that I don't want to work on now
// Look at source code of
// Attr.visitApply(JCMethodInvocation)
// resolveImplicitThis(DiagnosticPosition, Env, Type)
} else
throw new AssertionError("Unexpected type: " + methodSel.getKind());
नोट:
receiver
प्रकार TypeMirror
नहीं DeclaredType
दुर्भाग्य की जरूरत है। new int[5].clone()
पर कॉल करते समय, receiver
int[]
का होगा, जो पिछले विधि से अधिक जानकारीपूर्ण है।
यह
पिछले विधियों में से
दोनों को चलाने के लिए हो रही कक्षाओं के लिए प्रकार जानकारी को हल करने संकलक की आवश्यकता है। सामान्य परिस्थितियों में, कंपाइलर केवल विधि घोषणाओं के प्रकारों को हल करता है लेकिन निकायों को नहीं। इसलिए, पहले वर्णित विधियां null
बदलेगी।
संकलक प्रकार की जानकारी को हल करवाने के लिए, आप में से एक निम्न तरीकों कर सकते हैं:
1. उपयोग AbstractTypeProcessor
वर्ग है कि बस के लिए JDK 7. बाहर चेक काम संकलक भंडार करने के लिए जोड़ा गया JSR 308 और उनके कंपाइलर पर। जबकि काम मुख्य रूप से एनोटेटेड प्रकारों पर है, यह इसके लिए उपयोगी हो सकता है। संकलक आप जावा 5.
साथ एक पिछड़े संगत तरीके से प्रदान की कक्षा का उपयोग करने के यह दृष्टिकोण आप प्रोसेसर है कि बस अपने वर्तमान प्रोसेसर की तरह लागू करने के लिखने की अनुमति देता है।
2. इसके बजाय JavacTask
का उपयोग करें और JavacTask.analyze()
पर कॉल करें। this javac test की मुख्य विधि को देखने के लिए कक्षाओं पर अपने आगंतुक को आमंत्रित करने के लिए देखें।
यह दृष्टिकोण आपके प्रोसेसर को संकलक के प्लग-इन की बजाय विश्लेषण उपकरण की तरह दिखता है, क्योंकि आपको इसे नियमित प्रक्रिया होने के बजाय सीधे का आह्वान करना होगा।
प्रतिक्रिया के लिए धन्यवाद। हालांकि, रेखा: तत्व विधि = TreeInfo.symbol ((JCTree) node.getMethodSelect()); मेरे लिए शून्य वापस आती है। \t TypeMirror m = tree.getTypeMirror (पथ); भी \t टाइप एलिमेंट ई = (टाइप एलिमेंट) पेड़ .getElement (पथ); क्या मैं एक रूकी गलती कर रहा हूं और कुछ शुरू करने के लिए भूल रहा हूं, या गलत विधि को कॉल/ओवरराइड कर रहा हूं, या कुछ गड़बड़ कर रहा हूं? आपकी मदद के लिए फिर से धन्यवाद ... – runT1ME
मैंने अभी यह प्रविष्ट करने के लिए प्रविष्टि को अपडेट किया है कि क्यों विधियां शून्य हो जाती हैं और – notnoop
एफवाईआई को कैसे संबोधित किया जाए, एबीआरटीपीप्रोसेसर अब जेडीके 7 बिल्ड में उपलब्ध नहीं है, क्योंकि जेएसआर 308 के लिए समर्थन गिरा दिया गया था। –