2010-07-21 20 views
7

अरे, मुझे लगता है कि शीर्षक यह बताता है, लेकिन फिर भी।.class फ़ाइल का पूरी तरह से योग्य नाम कैसे पढ़ा जाए

मैं निकालनेअपने संकलित .class फ़ाइल से एक वस्तु की पूरी तरह से योग्य नाम की जरूरत है, किसी को भी सही दिशा में मुझे बिंदु सकता है?

धन्यवाद,
एडम।

उत्तर

11
getClass().getName() 

अद्यतन: आप एक byte[] (का उपयोग कर मानक आई/ओ) में classfile लोड कर सकते हैं और फिर getClass().getClassLoader().defineClass(...)

+0

मैं क्या नहीं कहा, मैं .class फ़ाइल से fqn पढ़ना चाहते हैं, वर्ग वस्तु के द्वारा किया क्रम में यह चाहते हैं स्मृति में लोड नहीं है। – TacB0sS

+0

@ TaCB0sS वह * क्लास नाम को .class फ़ाइल से पढ़ रहा है। मुझे लगता है कि आप अपना खुद का सवाल नहीं समझते हैं। –

+0

मुझे पता है कि मैं क्या चाहता हूं, मुझे अभी एहसास नहीं हुआ कि defullClass को एक शून्य को पारित किया जा सकता है। धन्यवाद, बोझो! – TacB0sS

0

आप जिस आईडीईई का उपयोग कर रहे हैं उसके आधार पर ऐसा करने के लिए एक तंत्र हो सकता है। उदाहरण के लिए ग्रहण में आप .class फ़ाइल पर ड्रिल कर सकते हैं और उस पर राइट क्लिक करें और "पूरी तरह से योग्य नाम कॉपी करें" का चयन करें। ग्रहण का

पुराने संस्करण इस सुविधा नहीं हो सकता है, लेकिन मैं पहले इस प्लगइन का इस्तेमाल किया है:

http://www.jave.de/eclipse/copyfully/index.html

यह बहुत ज्यादा काम करता है उसी तरह। उम्मीद है की यह मदद करेगा।

+0

अच्छा है कि, लेकिन मैं अपने आवेदन – TacB0sS

2

उपयोग BCEL की तरह एक पुस्तकालय का उपयोग स्मृति में classfile पढ़ सकते हैं और यह क्वेरी करने के लिए कक्षा के नाम के लिए।

+0

यह वह समाधान नहीं है जो मुझे दिमाग में था, मैं इसे खुद पढ़ना चाहूंगा, धन्यवाद। – TacB0sS

+0

फिर मैकडॉवेल के उत्तर से आपको सही दिशा में इंगित करना चाहिए। –

1

आप बाइनरी को पार्स करके इसे पढ़ सकते हैं। class file format को VM Spec में परिभाषित किया गया है।

यदि आप बाइनरी पार्स करने के लिए नए हैं तो DataInputStream पर एक नज़र डालें।

0

आप जेएसएफ कार्यान्वयन से एनोटेशन स्कैनर में उदाहरण के लिए एक उदाहरण ले सकते हैं, वे जेएसएफ एनोटेशन खोजने के लिए कक्षाओं को मैन्युअल रूप से (पैरा-स्पेस प्रदूषण से बचने के लिए) लोड करते हैं। इस पर विशेष नजर में:

/** 
    * This class is encapsulating binary .class file information as defined at 
    * http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html 
    * <p/> 
    * This is used by the annotation frameworks to quickly scan .class files 
    * for the presence of annotations. This avoid the annotation framework 
    * having to load each .class file in the class loader. 
    * <p/> 
    * Taken from the GlassFish V2 source base. 
    */ 
    @SuppressWarnings({"UnusedDeclaration"}) 
    private static final class ClassFile { 

     private static final int magic = 0xCAFEBABE; 

     public static final int ACC_PUBLIC = 0x1; 
     public static final int ACC_PRIVATE = 0x2; 
     public static final int ACC_PROTECTED = 0x4; 
     public static final int ACC_STATIC = 0x8; 
     public static final int ACC_FINAL = 0x10; 
     public static final int ACC_SYNCHRONIZED = 0x20; 
     public static final int ACC_THREADSAFE = 0x40; 
     public static final int ACC_TRANSIENT = 0x80; 
     public static final int ACC_NATIVE = 0x100; 
     public static final int ACC_INTERFACE = 0x200; 
     public static final int ACC_ABSTRACT = 0x400; 

     public short majorVersion; 
     public short minorVersion; 
     public ConstantPoolInfo constantPool[]; 
     public short accessFlags; 
     public ConstantPoolInfo thisClass; 
     public ConstantPoolInfo superClass; 
     public ConstantPoolInfo interfaces[]; 

     /** 
     * bunch of stuff I really don't care too much for now. 
     * <p/> 
     * FieldInfo   fields[]; MethodInfo   methods[]; 
     * AttributeInfo  attributes[]; 
     */ 

     ByteBuffer header; 
     ConstantPoolInfo constantPoolInfo = new ConstantPoolInfo(); 

     // ------------------------------------------------------------ Constructors 


     /** 
     * Creates a new instance of ClassFile 
     */ 
     public ClassFile() { 
      header = ByteBuffer.allocate(12000); 
     } 

     // ---------------------------------------------------------- Public Methods 


     public void setConstantPoolInfo(ConstantPoolInfo poolInfo) { 
      constantPoolInfo = poolInfo; 
     } 


     /** 
     * Read the input channel and initialize instance data structure. 
     * 
     * @param in a <code>ReadableByteChannel</code> that provides the bytes 
     * of the classfile 
     * 
     * @return <code>true</code> if the bytes representing this classfile include 
     * one of the annotations we're looking for. 
     * 
     * @throws IOException if an I/O error occurs while reading the class 
     */ 
     public boolean containsAnnotation(ReadableByteChannel in) 
       throws IOException { 

      /** 
      * this is the .class file layout 
      * 
      ClassFile { 
      u4 magic; 
      u2 minor_version; 
      u2 major_version; 
      u2 constant_pool_count; 
      cp_info constant_pool[constant_pool_count-1]; 
      u2 access_flags; 
      u2 this_class; 
      u2 super_class; 
      u2 interfaces_count; 
      u2 interfaces[interfaces_count]; 
      u2 fields_count; 
      field_info fields[fields_count]; 
      u2 methods_count; 
      method_info methods[methods_count]; 
      u2 attributes_count; 
      attribute_info attributes[attributes_count]; 
      } 
      **/ 
      header.clear(); 
      long read = (long) in.read(header); 
      if (read == -1) { 
       return false; 
      } 
      header.rewind(); 

      if (header.getInt() != magic) { 
       return false; 
      } 

      minorVersion = header.getShort(); 
      majorVersion = header.getShort(); 
      int constantPoolSize = header.getShort(); 

      return constantPoolInfo 
        .containsAnnotation(constantPoolSize, header, in); 

     } 

    } // END ClassFile 
4
public String getFullClassName(String classFileName) throws IOException {   
     File file = new File(classFileName); 

     FileChannel roChannel = new RandomAccessFile(file, "r").getChannel(); 
     ByteBuffer bb = roChannel.map(FileChannel.MapMode.READ_ONLY, 0, (int)roChannel.size());   

     Class<?> clazz = defineClass((String)null, bb, (ProtectionDomain)null); 
     return clazz.getName(); 
    }