2016-03-25 12 views
5

जावा में, मैं किसी विधि में उपयोग किए जाने वाले फ़ील्ड कैसे प्राप्त कर सकता हूं?जावा: किसी विधि में उपयोग किए गए सूची फ़ील्ड

असल में, यह this one in .NET जैसा ही प्रश्न है। मैं कक्षा से खेतों को सूचीबद्ध नहीं करना चाहता, लेकिन कक्षा के किसी दिए गए तरीके में उपयोग किए जाने वाले फ़ील्ड को सूचीबद्ध करना चाहता हूं।

उदाहरण:

public class A { 
int a; 
int b; 

public int bob(){ 
return a-b; 
} 

मैं इस तरह खेतों प्राप्त करना चाहते हैं:

Fields[] fields = FieldReader.(A.class.getMethod("bob")); 

ताकि fields[0]=A.a और fields[1]=A.b

मैं नहीं किसी भी समाधान मानक प्रतिबिंब का उपयोग कर मिला। क्या आपको लगता है कि ASM जैसे बाइटकोड मैनिपुलेशन लाइब्रेरी जाने का कोई तरीका है?

+0

क्या आप इस बारे में थोड़ा सा समझा सकते हैं कि आप ऐसा क्यों करना चाहते हैं? यदि आप संदर्भ की व्याख्या कर सकते हैं तो एक आसान तरीका होने की संभावना है। – sprinter

+0

यह अनुसंधान उद्देश्य के लिए है, मुझे तुलनित्र में उपयोग किए जाने वाले फ़ील्ड सूचीबद्ध करने की आवश्यकता है। – Julien

+1

आप http://asm.ow2.org/asm50/javadoc/user/org/objectweb/asm/MethodVisitor.html, अधिक विशिष्ट 'visitFieldInst' विधि का उपयोग कर सकते हैं। एएसएम मैनुअल पर देखो, यह एक अच्छा प्रारंभिक बिंदु है। – Grzesuav

उत्तर

2

यहां javassist के साथ एक उदाहरण है (आपको अपनी निर्भरता प्रबंधक वरीयताओं के आधार पर इसे निर्भरता के रूप में जोड़ने की आवश्यकता है)।

यह कोड public void doSomething(); विधि में फ़ील्ड को एक्सेस किया जा रहा है।

package bcm; 

import java.io.ByteArrayOutputStream; 
import java.io.IOException; 
import java.io.PrintStream; 

import javassist.CannotCompileException; 
import javassist.ClassPool; 
import javassist.CtClass; 
import javassist.CtMethod; 
import javassist.NotFoundException; 
import javassist.bytecode.InstructionPrinter; 

public class Person { 

    String name; 
    String surname; 
    int age; 

    boolean candrink = false; 

    public Person(String name, String surname, int age) { 
     super(); 
     this.name = name; 
     this.surname = surname; 
     this.age = age; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public String getSurname() { 
     return surname; 
    } 

    public void setSurname(String surname) { 
     this.surname = surname; 
    } 

    public int getAge() { 
     return age; 
    } 

    public void setAge(int age) { 
     this.age = age; 
    } 

    public void doSomething() { 
     if (this.age > 18) { 
      candrink = true; 
     } 
    } 

    public static void main(String[] args) throws IOException, 
      CannotCompileException { 
     ClassPool pool = ClassPool.getDefault(); 
     try { 
      CtClass cc = pool.get("bcm.Person"); 
      CtMethod m = cc.getDeclaredMethod("doSomething", null); 
      ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
      PrintStream ps = new PrintStream(baos); 
      InstructionPrinter i = new InstructionPrinter(ps); 
      i.print(m); 
      String content = baos.toString(); 

      for (String line : content.split("\\r?\\n")) { 
       if (line.contains("getfield")) { 
        System.out.println(line.replaceAll("getfield ", "")); 
       } 
      } 

     } catch (NotFoundException e) { 
      e.printStackTrace(); 
     } 
    } 

} 

HTH

+1

एएके, [स्ट्रिंग टाइपिंग] (http://c2.com/cgi/wiki?StringlyTyped)। – immibis

1

बार जब आप एक classnode लोड इस अविश्वसनीय रूप से आसान हो जाता है।

// Assuming you have loaded classNode 
for (MethodNode method : classNode.methods){ 
    for (AbstractInsnNode ain : method.instructions.toArray()) { 
     if (ain.getType() == AbstractInsnNode.FIELD_INSN) { 
      FieldInsnNode fin = (FieldInsnNode) ain; 
      //fin.name = Field name 
      //fin.owner = ClassNode's name 
     } 
    } 
} 

प्लस एएसएम जैवसिस्ट जैसे पुस्तकालयों की तुलना में बहुत तेज है।

+0

चूंकि प्रदर्शन एक चिंता है, इसलिए मैं इस समाधान पर स्विच कर सकता हूं। मैं दोनों दृष्टिकोणों की तुलना करने के लिए कुछ परीक्षण करूँगा – Julien

संबंधित मुद्दे