سؤال

هناك فئة مجردة:

public abstract class AbstractAny {
  private long period;

  public void doSomething() {
    // blah blah blah
    period = someHardcodedValue;
    // blah blah blah
  }
}

لا أرغب في تغيير مصدر الفصل الملخص ولكني بحاجة إلى إضافة بعض المرونة حول كيفية تعيين فترة الحقل.هل من الممكن تغيير قيمة فترة الحقل من طريقة التجاوز؟مثلا:

public class ConcreteSome extends AbstractAny{
  @Override
  public void doSomething() {
    try {
      Field p = super.getClass().getDeclaredField("period");
      p.setAccessible(true);
      p.setLong(this, 10L);
    } catch (SecurityException e) {
        throw new RuntimeException(e);
    } catch (NoSuchFieldException e) {
        throw new RuntimeException(e);
    } catch (IllegalArgumentException e) {
        throw new RuntimeException(e);
    } catch (IllegalAccessException e) {
        throw new RuntimeException(e);
    }
  }
}

عندما أحاول تشغيل هذا الرمز super.getClass().getDeclaredField("period") رميات java.lang.NoSuchFieldException: period

هل كانت مفيدة؟

المحلول

انت تحتاج getClass().getSuperclass() للحصول على الطبقة المتفوقة، لا super.getClass().

ومع ذلك، أنا حقًا لا تنصح بفعل هذا.أنت تقوم بشكل أساسي بتدمير تغليف الفئة المجردة.إذا كانت الفئة المجردة لا توفر المرونة الكافية لأحفادها، فيجب إصلاحها - فالالتفاف حولها لا يؤدي إلا إلى حدوث مشكلة.ماذا لو احتاج عضو آخر في الفصل المجرد إلى التغيير كلما فعل ذلك هذا العضو؟الهدف الأساسي من وجود حالة خاصة هو أن يتمكن الفصل من حماية بياناته الخاصة.يعد استخدام الانعكاس مثل هذا بمثابة اختراق قبيح حقًا ويجب أن يكون مطلقًا آخر ملجأ.

نصائح أخرى

وأنا مع جون السكيت. انه من الاسهل على المدى البعيد لتغيير شفرة المصدر الفائقة لجعل إما هذا المجال حماية أو تفويض طفرة إلى أسلوب للتجاوز. عن طريق انعكاس لتغيير القيمة يعمل طيب الآن، لكنه لا مقياس جيد للغاية بقدر الحفاظ على مرور الوقت.

وConcreteSome لا تمديد AbstractAny فئة مجردة.
جرب هذا

public class ConcreteSome {
    @Override
    public void doSomething() {
        Class<?> clazz = getClass().getSuperclass();
        System.out.println(clazz);
        Field p = clazz.getDeclaredField("period");
        ...

ويجب أن تعود java.lang.Object

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top