2013-07-23 152 views
1

我對Java相當陌生,並對此處的最佳實踐感到疑惑。使用類註釋或靜態屬性

假設我有一個泛型類(例如Car)和一些共享某些屬性的繼承類(Honda,Subaru)。

public abstract class Car { 
    public static short id; 
} 

public class Honda extends Car { 
    public static final short id = 1; 
} 

public class Subaru extends Car { 
    public static final short id = 2; 
} 

這是不是違背了DRY原則?那麼使用註釋呢?

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.TYPE) 
public @interface Id { 
    public short value(); 
} 

public abstract class Car { 
} 

@Id(1) 
public class Honda extends Car { 
} 

@Id(2) 
public class Subaru extends Car { 
} 
+4

既不是你的'Car'是通用的,也不是你的其他類繼承它。 –

+0

你的課程已經有一個ID。他們被稱爲「汽車」,「本田」和「斯巴魯」。這些名稱可以使用反射來檢索。您可能需要的唯一附加ID是'serialVersionUID',但是這個ID是專門針對類實現的,因此不會違反DRY原則。 –

+0

請注意,您不能繼承「靜態」成員(字段和方法)。 (好吧,在之前的評論中,「你可能需要的唯一附加ID」就是誇大了它) –

回答

0

這當然有點味道的問題。我不會向你推薦這個。 註解是元信息標記字段,方法和類。 id(或nbSeats)相當於一個字段而不是註釋。

我會在你的情況比較喜歡這個:

public abstract class Car { 
    protected static short id; 

    public static short getId() { 
     return id; 
    } 
} 

class Honda extends Car { 
    static { 
     id = 1; 
    } 
} 

class Subaru extends Car { 
    static { 
     id = 2; 
    } 
} 

編輯:對不起:這個解決方案是有嚴重缺陷的:-( 爲汽車本田斯巴魯共享同場 。看看那個:

public static void main(String[] args) { 
     new Honda(); 
     new Subaru(); 
     System.out.println(Honda.getId()); 
     System.out.println(Subaru.getId()); 
} 

結果在

2 
2 

我覺得這個解決方案可能會更好:

public abstract class Car { 
    protected abstract short id(); 

    public static short getIdOf(Class<? extends Car> carClass) 
      throws InstantiationException, IllegalAccessException { 
     return carClass.newInstance().id(); 
    } 

    public static void main(String[] args) throws InstantiationException, 
      IllegalAccessException { 
     System.out.println(Car.getIdOf(Honda.class)); 
     System.out.println(Car.getIdOf(Subaru.class)); 
    } 
} 

class Honda extends Car { 
    protected short id() { 
     return 1; 
    } 
} 

class Subaru extends Car { 
    protected short id() { 
     return 2; 
    } 
} 

它具有一定的優勢:

  • 它強制汽車的每一個具體的子類有一個ID(通過實現ID( ))。
  • 它隱藏汽車的sublasses到超類汽車
  • 編譯器可檢查僅汽車的子類被傳遞給getIdOf()
  • 它強制類加載器加載的類(靜態初始化只有在類加載時才執行!)
  • 許多其他

它也有一些缺點:

  • 它需要Java反射
  • 的ID() - 方法是非靜態的需要
  • 實例調用ID( )
  • 它要求所有小類中的默認公共構造函數
  • 您可以傳遞抽象子集SES到getIdOf()
  • 許多其他

請記住,註釋的參數的種類僅限於原語類型,字符串,類,註釋,枚舉和一維數組!