نمط باني جافا مع حدود النوع العام
-
27-09-2019 - |
سؤال
أحاول إنشاء فئة مع العديد من المعلمات ، باستخدام نمط البناء بدلاً من مُنشئات التلسكوب. أقوم بذلك بالطريقة التي وصفها JoShua Bloch الفعالة ، ولديها مُنشئ خاص على الفصل المرفق ، وفئة منشئ ثابت عام. تضمن فئة البناء أن يكون الكائن في حالة متسقة قبل استدعاء Build () ، وعندها تقوم بتفويض بناء الكائن المرفق إلى المُنشئ الخاص. هكذا
public class Foo {
// Many variables
private Foo(Builder b) {
// Use all of b's variables to initialize self
}
public static final class Builder {
public Builder(/* required variables */) {
}
public Builder var1(Var var) {
// set it
return this;
}
public Foo build() {
return new Foo(this);
}
}
}
ثم أريد إضافة حدود نوع إلى بعض المتغيرات ، وبالتالي أحتاج إلى تحديد تعريف الفئة. أريد أن تكون حدود فئة FOO هي نفس حدود فئة البناء.
public class Foo<Q extends Quantity> {
private final Unit<Q> units;
// Many variables
private Foo(Builder<Q> b) {
// Use all of b's variables to initialize self
}
public static final class Builder<Q extends Quantity> {
private Unit<Q> units;
public Builder(/* required variables */) {
}
public Builder units(Unit<Q> units) {
this.units = units;
return this;
}
public Foo build() {
return new Foo<Q>(this);
}
}
}
هذا يجمع بشكل جيد ، لكن المترجم يسمح لي بالقيام بالأشياء التي أشعر أنها يجب أن تكون أخطاء في البرمجيات. على سبيل المثال
public static final Foo.Builder<Acceleration> x_Body_AccelField =
new Foo.Builder<Acceleration>()
.units(SI.METER)
.build();
هنا حجة الوحدات ليست كذلك Unit<Acceleration>
لكن Unit<Length>
, ، ولكن لا يزال مقبول من قبل المترجم.
ماذا أفعل خطأ هنا؟ أرغب في التأكد من أن أنواع الوحدات تتطابق بشكل صحيح.
المحلول
units
يجب أن تعود Builder<Q>
, ، ليس غير منشئ Builder
.
نصائح أخرى
على الرغم من أن @Daniel's Point صالحة ، إلا أن الخطأ في الكود الخاص بك يتم رصده بواسطة Eclipse على الأقل. بالطبع ، تعريفك لـ Quantity
, Unit
و METER
ربما يختلف عن الاختراق البسيط الذي وضعته معًا:
interface Quantity {
}
class Acceleration implements Quantity {
}
class Length implements Quantity {
}
public class Unit<Q extends Quantity> {
public static final Unit<Length> METER = new Unit<Length>();
}
public static final Foo.Builder<Acceleration> x_Body_AccelField =
new Foo.Builder<Acceleration>()
.units(Unit.METER) // here the compiler complains
.build();
رسالة الخطأ هي:
The method units(Unit<Acceleration>) in the type Foo.Builder<Acceleration> is
not applicable for the arguments (Unit<Length>)