2013-06-23 5 views
10

मैं प्रोग्रामिंग के उप-वर्ग बनाना चाहता हूं। मुझे लगता है कि मेरे पास कुछ विकल्प हैं - जैविसिस्ट, सीजीएलआईबी, बीसीईएल, या एएसएम।जावा - एक सबक्लास गतिशील रूप से

उपयोग का मामला यह है कि एक ऐप के आंतरिक वर्ग-उन्मुख होते हैं, और एक्सटेंशन कक्षा-आधारित होते हैं। इसलिए मेरे पास बाह्य स्क्रिप्ट द्वारा संचालित एकाधिक एक्सटेंशन के लिए आधार के रूप में एक एकल वर्ग नहीं हो सकता है।

अब - मैं यह कैसे करूँगा? मुझे इंटरसेप्टिंग विधि कॉल, फ़ील्ड एक्सेस, प्रारंभिक इत्यादि के साथ उदाहरण मिल गए हैं लेकिन सबक्लासिंग के बारे में कुछ नहीं।

मैं एक वर्ग के साथ खत्म करना चाहते हैं जो:

  • एक नाम जो मैं चाहता हूँ है।
  • माता पिता वर्ग से किसी वर्ग
  • प्रतियां निर्माता (रों) के एक (प्रत्यक्ष, सबसे अच्छे रूप) उपवर्ग है (या super(...) कॉल) अंत में
  • , मैं यह तो कुछ टिप्पणियां देना चाहते हैं।

मुझे पता है कि यह संभव है क्योंकि GroovyClassLoader जैसे विभिन्न गतिशील भाषाओं के एकीकरण, ऐसा कर सकते हैं।

उत्तर

5

यह Javassist के साथ काफी आसान है:

import javassist.CannotCompileException; 
import javassist.ClassPool; 
import javassist.CtClass; 
import javassist.NotFoundException; 

static Class<? extends DefinitionBasedMigrator> createClass(String fullName) 
     throws NotFoundException, CannotCompileException 
{ 
    ClassPool pool = ClassPool.getDefault(); 

    // Create the class. 
    CtClass subClass = pool.makeClass(fullName); 
    final CtClass superClass = pool.get(DefinitionBasedMigrator.class.getName()); 
    subClass.setSuperclass(superClass); 
    subClass.setModifiers(Modifier.PUBLIC); 

    // Add a constructor which will call super(...); 
    CtClass[] params = new CtClass[]{ 
     pool.get(MigratorDefinition.class.getName()), 
     pool.get(GlobalConfiguration.class.getName()) 
    }; 
    final CtConstructor ctor = CtNewConstructor.make(params, null, CtNewConstructor.PASS_PARAMS, null, null, subClass); 
    subClass.addConstructor(ctor); 

    return subClass.toClass(); 
} 

Maven निर्भरता:

<!-- https://mvnrepository.com/artifact/org.javassist/javassist --> 
<dependency> 
    <groupId>org.javassist</groupId> 
    <artifactId>javassist</artifactId> 
    <version>3.22.0-GA</version> 
</dependency> 
2

जावा प्रॉक्सी तुम क्या आवश्यकता होती है ऐसा करने में सक्षम हो सकता है - वे अनिवार्य रूप से आप गतिशील रूप से एक के शीर्ष पर कार्यक्षमता परत करने की अनुमति ऑब्जेक्ट, क्योंकि आप उस ऑब्जेक्ट को किसी भी विधि कॉल को रोक सकते हैं, और या तो स्वयं को संभाल सकते हैं या अंतर्निहित कक्षा में विधि कॉल भेज सकते हैं। आप जो करना चाहते हैं उसके आधार पर, हो सकता है कि आप एक ही परिणाम प्राप्त कर सकें जैसे आप उप-वर्ग गतिशील रूप से

ओरेकल की वेबसाइट पर decent introduction है (URL संदर्भ जावा संस्करण 1.4.2, लेकिन मुझे नहीं लगता कि इसका हालिया संस्करणों में इसका व्यवहार बदल गया है)। यहां एक more concise example है जो प्रॉक्सी कोड की तरह दिखने के लिए एक अच्छा स्वाद देता है।

डायरेक्ट बाइट कोड मैनिपुलेशन (ASM framework द्वारा समर्थित) का उपयोग करके चीजों को करना भी संभव है, हालांकि मुझे लगता है कि प्रॉक्सी का उपयोग करना एक आसान तरीका होगा।

+0

वास्तव में मैंने पहले प्रॉक्सी को देखा लेकिन जटिलता के कारण छोड़ दिया। जावासवादी इतना आसान है। और, प्रॉक्सी को एक इंटरफ़ेस की आवश्यकता होती है और इसे सामान्य कक्षाओं के रूप में आगे नहीं बढ़ाया जा सकता है ... वैसे भी, +1 –

7

एक लाइब्रेरी जिसे मैं विशेष रूप से शौकीन हूं, का उपयोग यहां किया जा सकता है; Bytebuddy

Class<?> dynamicType = new ByteBuddy() 
    .subclass(Object.class) 
    .method(ElementMatchers.named("toString")) 
    .intercept(FixedValue.value("Hello World!")) 
    .make() 
    .load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER) 
    .getLoaded(); 

यह अविश्वसनीय रूप से लचीला और निश्चित रूप से बाहर की जाँच करता है, तो आप अपने बालों को रखना चाहते हैं लायक है, मैं व्यक्तिगत रूप से javassist की भारी प्रयोग लगता है काफी बदसूरत प्राप्त कर सकते हैं:

उदाहरण लैंडिंग पृष्ठ से सीधे लिया और कई बार गन्दा, बाइटबड्डी ताजा हवा की एक अच्छी तरह से आवश्यक सांस की तरह लगता है!

Rafael Winterhalter स्टैक ओवरफ्लो पर भी सक्रिय है जो किसी भी चीज को सुनिश्चित करने में आपकी सहायता करता है।

संपादित करें: नेक्रोप्रोस्टिंग के लिए मेरी क्षमा।यहां एक लैंड किया गया जब एक दोस्त ने सवाल जोड़ा और तिथि की जांच करना भूल गया।

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