假设我有两个类A和B,其中B扩展A.当我创建B的实例时,调用A和B的构造函数。确定在创建实例B时是否正在调用A的构造函数的最佳方法是什么?
我做了类似下面的事情,但看起来并不美观。我正在使用getClass()
,有更好的方法吗?我实际上是在尝试计算A和B的实例。
public class A {
private static int counter = 0;
public A() {
if (this.getClass().getName().equals("A")) {
counter++;
}
}
public static void main(String[] args) {
A a = new B();
A a1 = new A();
A a2 = new B();
System.out.println(A.getCount());
System.out.println(B.getCount());
}
public static int getCount() {
return counter;
}
}
class B extends A {
private static int counter = 0;
public B() {
counter++;
}
public static int getCount() {
return counter;
}
}
输出
1
2
答案 0 :(得分:4)
最好避免检查名称:
if (this.getClass() == A.class)
除此之外,您可以考虑使用protected
构造函数 - 但仍然可以在同一个包中访问。
通常,最好的解决方案是不需要这样做 - 如果你的设计真的需要知道你正在构建的对象是否只是一个A"或者是子类的一个实例,那么上面的测试非常清楚地表示了这个条件......但是从一开始就是一个奇怪的要求。
答案 1 :(得分:1)
我建议你在多个构造函数的情况下使用initialization block
,否则你必须在每个构造函数中重复你的代码。
示例代码:
public class A {
private static int counter = 0;
// initialization block
{
if (this.getClass() == A.class) {
counter++;
}
}
public A() {
}
public A(int i) {
}
public A(String s) {
}
public static int getCount() {
return counter;
}
}
答案 2 :(得分:0)
编辑:在阅读之前,我只是看到别人的答案,这有助于以类似的方式。这种方式不会使用反射。
正如其他人所说,你不应该担心你的超类中的子类。如果你真的想要这样的控制:
public class Test {
public static void main(String[] args) {
B b = new B("hey");
C c = new C(5);
}
}
class A {
public A(int age) { //specifically for B
System.out.println("B created");
}
public A(String name) { //specifically for C
System.out.println("C created");
}
{ //for all constructors
System.out.println("An instance that extend A have been created");
}
}
class B extends A {
public B(String name) {
super(name);
}
}
class C extends A {
public C(int age) {
super(age);
}
}
虽然这是不好的做法,因为构造函数中的params不应该以这种方式被忽略(无用的参数只是为了排序)。这将使阅读代码的其他开发人员感到困惑。这是可能的,但问题是,你为什么要这样做?最有可能是更好/更清洁/更有效的方式来完成任务
答案 3 :(得分:0)
来自@Braj @JonSkeet的好建议
我实现了类似下面的内容
import java.util.HashMap;
class ClassCounter{
private static HashMap<Class<?>, Integer> mapClassCount= new HashMap<>();
public static void increment(Class<?> clz){
Integer cnt = mapClassCount.get(clz);
if(cnt == null){
cnt = new Integer(0);
}
mapClassCount.put(clz, ++cnt);
}
public static Integer get(Class<?> clz){
Integer cnt = mapClassCount.get(clz);
return ((cnt == null) ? 0: cnt);
}
}
public class A {
{
if (this.getClass().equals(A.class)) {
ClassCounter.increment(A.class);
}
}
public A() {
}
public static void main(String[] args) {
A a = new B();
A a1 = new A();
A a2 = new B();
System.out.println(ClassCounter.get(A.class));
System.out.println(ClassCounter.get(B.class));
}
}
class B extends A {
{
ClassCounter.increment(B.class);
}
public B() {
}
}