كيفية تحويل حقل خاص من فئة مجردة في جافا؟
-
10-07-2019 - |
سؤال
هناك فئة مجردة:
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