लोम्बोक में सुपर कंस्ट्रक्टर को कैसे कॉल करें


118

मुझे कक्षा में जाना है

@Value
@NonFinal
public class A {
    int x;
    int y;
}

मेरे पास एक और क्लास बी है

@Value
public class B extends A {
    int z;
}

lombok यह कहते हुए त्रुटि को फेंक रहा है कि यह केंट नहीं मिल रहा है A () कंस्ट्रक्टर, स्पष्ट रूप से इसे कॉल करें कि मैं क्या करना चाहता हूँ lombok वर्ग बी को एनोटेशन देना है जैसे कि यह निम्नलिखित कोड उत्पन्न करता है:

public class B extends A {
    int z;
    public B( int x, int y, int z) {
        super( x , y );
        this.z = z;
    }
}

क्या हमारे पास लोम्बोक में ऐसा करने का एनोटेशन है?

जवाबों:


169

लोम्बोक में यह संभव नहीं है। हालांकि यह एक बहुत अच्छी सुविधा होगी, लेकिन सुपर क्लास के कंस्ट्रक्टर्स को खोजने के लिए इसे रिज़ॉल्यूशन की आवश्यकता होती है। सुपर क्लास को केवल उसी नाम से जाना जाता है जिस दिन लोम्बोक को बुलाया जाता है। आयात कथनों का उपयोग करना और वास्तविक वर्ग को खोजने के लिए क्लासपाथ तुच्छ नहीं है। और संकलन के दौरान आप केवल निर्माणकर्ताओं की सूची प्राप्त करने के लिए प्रतिबिंब का उपयोग नहीं कर सकते।

यह पूरी तरह से असंभव नहीं है, लेकिन में संकल्प का उपयोग कर परिणाम valऔर @ExtensionMethodहै कि हमें सिखाया है यह मुश्किल और त्रुटि प्रवण।

प्रकटीकरण: मैं एक लोम्बोक डेवलपर हूं।


@ रोएल-स्पिलकर हम इसके पीछे की जटिलताओं को समझते हैं। लेकिन क्या लोम्बोक inConstructorकंस्ट्रक्टर एनोटेशन के लिए एक विधि प्रदान कर सकता है जहां हम निर्दिष्ट कंस्ट्रक्टर में लेम्बोक के किस कंस्ट्रक्टर को निर्दिष्ट कर सकते हैं super?
मनु मंजूनाथ

1
afterConstructor कुछ स्वत: इनिशियलाइज़ेशन करने के लिए अच्छा होगा
पावेल

@ मनु / @ पावेल:
लोंबोक

चूँकि @Builder आधिकारिक रिलीज़ में है: github.com/rzwitserloot/lombok/issues/853
सेबस्टियन

4
अभी भी संभव नहीं है?
1932 में फियरएक्स

22

लंबोक अंक # 78 इस पृष्ठ का संदर्भ देता है https://www.donneo.de/2015/09/16/lomboks-builder-annotation-and-inheritance/ इस प्यारी सी व्याख्या के साथ:

@AllArgsConstructor 
public class Parent {   
     private String a; 
}

public class Child extends Parent {
  private String b;

  @Builder
  public Child(String a, String b){
    super(a);
    this.b = b;   
  } 
} 

परिणामस्वरूप आप इस तरह उत्पन्न बिल्डर का उपयोग कर सकते हैं:

Child.builder().a("testA").b("testB").build(); 

आधिकारिक दस्तावेज इस बताते हैं, लेकिन यह स्पष्ट रूप से कहना नहीं है कि आप इसे इस तरह से मदद कर सकते हैं।

मैंने यह भी पाया कि स्प्रिंग डेटा JPA के साथ अच्छी तरह से काम करता है।


क्या आप इसका एक उदाहरण स्प्रिंग डेटा जेपीए के साथ उपयोग कर सकते हैं?
मार्क ज़म्पेटी

29
यह प्रश्न का उत्तर नहीं देता है। इसके बजाय, यह हाथ से काम करता है, जबकि सवाल यह था कि इसे कैसे उत्पन्न किया जाए। इसी समय, यह @Builder को खींचकर पूरी बात को और अधिक भ्रमित कर देता है, जिसका सवाल से कोई लेना-देना नहीं है।
जैस्पर

8
वास्तव में यह उन लोगों के लिए बहुत उपयोगी है जो सिर्फ एक विरासत संरचना बनाना चाहते हैं और फिर बिल्डर का उपयोग करते हैं। यह 99% कारण है मैं #lombok वैसे भी उपयोग करता हूं। कभी-कभी हमें सिर्फ अपनी इच्छा के अनुसार काम करने के लिए सामान को हाथ लगाना पड़ता है। धन्यवाद @ jj-zabkar
Babajide Prince

परन्तु फिर; बस स्व + माता पिता arg निर्माता कोड।
Juh_

यह STS और ग्रहण में काम करेगा, लेकिन जब आप अपने एप्लिकेशन की JAR फ़ाइल बनाते हैं, तो संभवतः यह विफल हो जाएगा। मैं दोनों SuperBuilder, विरासत के लिए बिल्डर की कोशिश की। दोनों फेल हो गए। सावधान रहे !!
पी सतीश पात्रो

6

लोम्बोक समर्थन नहीं करता है जो किसी भी @Valueएनोटेट वर्ग final(जैसा कि आप उपयोग करके जानते हैं @NonFinal) बनाकर इंगित किया गया है ।

मेरे द्वारा पाया गया एकमात्र समाधान यह है कि सभी सदस्य अपने आप को अंतिम घोषित करें और @Dataइसके बजाय एनोटेशन का उपयोग करें । उन उपवर्गों को एनोटेट करने की आवश्यकता है @EqualsAndHashCodeऔर एक स्पष्ट सभी आर्ग कंस्ट्रक्टर की आवश्यकता है क्योंकि लोम्बोक को पता नहीं है कि सुपर आर्ग के सभी आर्ग में से एक का उपयोग करके कैसे बनाएं:

@Data
public class A {
    private final int x;
    private final int y;
}

@Data
@EqualsAndHashCode(callSuper = true)
public class B extends A {
    private final int z;

    public B(int x, int y, int z) {
        super(x, y);
        this.z = z;
    }
}

विशेष रूप से उपवर्गों के निर्माता कई सदस्यों के साथ सुपरक्लास के लिए समाधान को थोड़ा अयोग्य बनाते हैं, क्षमा करें।


1
क्या आप थोड़ा और समझा सकते हैं कि "उपवर्गों को एनोटेट करने की आवश्यकता क्यों है @EqualsAndHashCode"? क्या यह एनोटेशन शामिल नहीं है @Data? Thx :)
जेरार्ड बॉश

1
@GardardB @Dataभी बराबरी () और हैशकोड () बनाता है, लेकिन किसी भी विरासत के बारे में परवाह नहीं करता है। यह सुनिश्चित करने के लिए कि सुपरक्लास के बराबर () और हैशकोड () का उपयोग किया जाता है, आपको कॉलसुपर के साथ स्पष्ट पीढ़ी की आवश्यकता है
Arne Burmeister

5

कई सदस्यों के साथ सुपरक्लास के लिए मैं आपको @Delegate का उपयोग करने का सुझाव दूंगा

@Data
public class A {
    @Delegate public class AInner{
        private final int x;
        private final int y;
    }
}

@Data
@EqualsAndHashCode(callSuper = true)
public class B extends A {
    private final int z;

    public B(A.AInner a, int z) {
        super(a);
        this.z = z;
    }
}

यह एक दिलचस्प दृष्टिकोण है, जैसे यह!
अर्ने बर्मिस्टर

@Delegateहै @Target({ElementType.FIELD, ElementType.METHOD})AInner में फील्ड होना चाहिए A
बोरिसलेक

3

यदि चाइल्ड क्लास में माता-पिता की तुलना में अधिक सदस्य हैं, तो यह बहुत साफ नहीं किया जा सकता है, लेकिन संक्षिप्त रूप से:

@Data
@RequiredArgsConstructor
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class User extends BaseEntity {
    private @NonNull String fullName;
    private @NonNull String email;
    ... 

    public User(Integer id, String fullName, String email, ....) {
        this(fullName, email, ....);
        this.id = id;
    }
}

@Data
@AllArgsConstructor
abstract public class BaseEntity {
   protected Integer id;

   public boolean isNew() {
      return id == null;
   }
}

3

लंबोक के संस्करण 1.18 ने @SuperBuilder एनोटेशन पेश किया। इसका उपयोग हम अपनी समस्या को सरल तरीके से हल करने के लिए कर सकते हैं।

आप https://www.baeldung.com/lombok-builder-inheritance#lombok-builder-and-inheritance-3 का संदर्भ ले सकते हैं ।

आपके बच्चे की कक्षा में, आपको इन टिप्पणियों की आवश्यकता होगी:

@Data
@SuperBuilder
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)

अपने मूल वर्ग में:

@Data
@SuperBuilder
@NoArgsConstructor

0

एक विकल्प के रूप में आप com.fasterxml.jackson.databind.ObjectMapperमाता-पिता से एक बच्चे की कक्षा को इनिशियलाइज़ करने के लिए उपयोग कर सकते हैं

public class A {
    int x;
    int y;
}

public class B extends A {
    int z;
}

ObjectMapper MAPPER = new ObjectMapper(); //it's configurable
MAPPER.configure( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false );
MAPPER.configure( SerializationFeature.FAIL_ON_EMPTY_BEANS, false );

//Then wherever you need to initialize child from parent:
A parent = new A(x, y);
B child = MAPPER.convertValue( parent, B.class);
child.setZ(z);

आप अभी भी lombokए और बी पर किसी भी एनोटेशन का उपयोग कर सकते हैं यदि आप की जरूरत है।

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