有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java确定对象属性的数据类型

我在Java/Groovy中有两个类似的对象,比如:

class a {
    Date creation
}

class a {
    String creation
}

在我的程序中,有一个开关决定我应该使用哪个对象(Groovy代码):

def obj
if(/* certain criteria for a */) {
    obj = new package.foo.a()

    // ...
    // Or some other process aside from initialization.
}
else if(/* certain criteria for the another a */) {
    obj = new package.bar.a()

    // ...
    // Or some other process aside from initialization.

}
else {
    obj = null
}

在代码的后面,我需要根据属性creation的类型确定应该执行的过程:

if(obj.creation instanceof Date) {
    obj.creation = new Date()
}
else if(obj.creation instanceof String) {
    obj.creation = '1995-08-17'
}

上面的代码不起作用。有没有办法做到这一点?当然,如果无法获取属性的数据类型,我始终可以执行以下操作:

if(obj instanceof package.foo.a) {
    obj.creation = new Date()
}
else if(obj instanceof package.bar.a) {
    obj.creation = '1995-08-17'
}

共 (3) 个答案

  1. # 1 楼答案

    有时需要根据对象的类型进行修改,但应该避免,因为这样会使代码更加脆弱。您可能会在代码库中到处都是类型检查。在您的情况下,您可以将特定于类的行为委托给类本身。下面是一个例子:

    class A {
        Date creation
    
        void initializeCreationDate() {
            creation = new Date()
        }
    }
    
    /* I'm using a different class name to make this
     * example self-contained.
     */
    class B {
        String creation
    
        void initializeCreationDate() {
            creation = '1995-08-17'
        }
    }
    
    def obj
    def condition = true
    
    if(condition) {
        obj = new A()
    } else {
        obj = new B()
    }
    
    obj.initializeCreationDate()
    

    在本例中,两个类负责设置自己的创建日期。这有助于保持代码整洁

    使用mixin代替

    即使无法(或不想)修改这两个类的源代码,您仍然可以实现相同的效果。在这种情况下,可以使用mixin添加initializeCreationDate()方法。像这样:

    class A {
        Date creation
    }
    
    /* I'm using a different class name to make this
     * example self-contained.
     */
    class B {
        String creation
    }
    
    class DateInitializer {
        static void initializeCreationDate(A object) {
            object.creation = new Date()
        }
    
        static void initializeCreationDate(B object) {
            object.creation = '1995-08-17'
        }
    }
    
    def obj
    def condition = true
    
    if(condition) {
        obj = new A()
    } else {
        obj = new B()
    }
    
    obj.metaClass.mixin DateInitializer
    obj.initializeCreationDate()
    
  2. # 2 楼答案

    它不工作,因为创建为空。null不是任何对象的实例。 必须使用反射API获取字段类型,然后使用Class.isAssignableFrom()检查类型

    if(String.class.isAssignableFrom(a.class.getDeclaredField("creation").getType()){
       ...
    }
    

    我对其进行了编辑,以使代码能够编译:)

  3. # 3 楼答案

    您可以尝试获取对象的class,并检查它是否与正在检查的任何类型的class相同:

    if(obj.creation.getClass().equals(Date.class)) {
        obj.creation = new Date();
    }
    else if(obj.creation.getClass().equals(String.class)) {
        obj.creation = "1995-08-17";
    }