使用类注释或静态属性

时间:2013-07-23 10:16:05

标签: java annotations static-members

我对Java很新,并且想知道这里的最佳实践。

假设我有一个通用类(例如Car),以及一些共享某些属性的继承类(HondaSubaru)。

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 {
}

1 个答案:

答案 0 :(得分: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;
    }
}
编辑:对不起:这个解决方案存在很大缺陷:-( 如 Car Honda Subaru 共享相同的字段。 看看:

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

它有一些优点:

  • 它强制 Car 的每个具体子类都有一个id(通过实现id())。
  • 它将 Car 的子类隐藏到超类 Car
  • 编译器可以检查是否只将 Car 的子类传递给getIdOf()
  • 它强制类加载器加载类(静态初始化器只在加载类时执行!)
  • 许多其他人

它有一些缺点:

  • 需要java反射
  • id() - 方法是非静态的
  • 需要实例来调用id()
  • 它要求所有子类中的默认公共构造函数
  • 您可以将抽象子类传递给getIdOf()
  • 许多其他人

请记住,注释参数的类型仅限于基本类型,字符串,类,注释,枚举和1维数组!