2010-05-17 35 views
5

Tôi đang cố gắng tạo một lớp có nhiều tham số, sử dụng mẫu Builder hơn là các nhà xây dựng lồng ghép. Tôi đang làm điều này theo cách được mô tả bởi Java hiệu quả của Joshua Bloch, có hàm tạo riêng tư trên lớp kèm theo, và một lớp Trình dựng tĩnh công cộng. Lớp Builder đảm bảo đối tượng ở trạng thái nhất quán trước khi gọi build(), tại thời điểm đó nó ủy nhiệm việc xây dựng đối tượng kèm theo cho hàm tạo riêng. Do đó,Mô hình Java Builder với các giới hạn kiểu chung

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); 
     } 

    } 

} 

Sau đó, tôi muốn thêm các giới hạn kiểu vào một số biến và do đó cần tham số định nghĩa lớp. Tôi muốn giới hạn của lớp Foo giống như lớp Builder.

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); 
     } 

    } 

} 

Điều này biên dịch tốt, nhưng trình biên dịch cho phép tôi làm những điều tôi cảm thấy là lỗi trình biên dịch. Ví dụ.

public static final Foo.Builder<Acceleration> x_Body_AccelField = 
     new Foo.Builder<Acceleration>() 
     .units(SI.METER) 
     .build(); 

đây đối số đơn vị không phải là Unit<Acceleration> nhưng Unit<Length>, nhưng nó vẫn được chấp nhận bởi trình biên dịch.

Tôi đang làm gì sai ở đây? Tôi muốn đảm bảo thời gian biên dịch các loại đơn vị khớp đúng.

Trả lời

6

units phải trả lại Builder<Q>, không phải là không được sửa lỗi Builder.

+0

Cảm ơn bạn, tôi đã không suy nghĩ rất rõ ràng trong vấn đề đó. – I82Much

0

Mặc dù điểm của @ Daniel là hợp lệ, ít nhất là lỗi trong mã của bạn được phát hiện bởi Eclipse. Tất nhiên, định nghĩa của bạn về Quantity, UnitMETER có lẽ là khác nhau từ việc hack đơn giản tôi đặt lại với nhau:

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(); 

Các thông báo lỗi là:

The method units(Unit<Acceleration>) in the type Foo.Builder<Acceleration> is 
not applicable for the arguments (Unit<Length>) 
+0

Thú vị. Tôi đã sử dụng NetBeans, vốn không phàn nàn. Hệ thống phân cấp đơn vị tôi đang sử dụng đến từ JSR 275 (http://download.java.net/maven/2/net/java/dev/jsr-275/jsr-275/1.0-beta-2/) và JScience (http://jscience.org/) – I82Much

+2

Bạn sẽ nhận được lỗi đó ngay cả trong NetBeans ... nếu không, đó là một lỗi rất xấu. Sự khác biệt trong mã ban đầu của bạn là nếu bạn có một thuộc tính trung gian: new Foo.Builder (). Pho mát (GOUDA) .units (Unit.METER), trong đó phương thức 'cheese' trả về Builder không phải là Builder . – Cowan

Các vấn đề liên quan