繁体   English   中英

java static 摘要方法 class

[英]java static method for abstract class

我有一个 java 摘要 class 声明扩展 class 为“JsonSerializable”

public abstract class JsonSerializable {
    private final String path;

    public JsonSerializable(String path) {
        this.path = path;
    }
} 

现在,如果我尝试“加载”一个扩展JsonSerializable的 class,我需要获取我想要加载的 class 的“文件路径”。 我目前这样做的方式如下:

private static <T extends JsonSerializable> T getNew(Class<T> tClass) throws [...] {
        return tClass.getDeclaredConstructor().newInstance();
}

但是,如果构建一个新的 class(我正在尝试加载的类型)有一些副作用(例如,在初始化时,class 在另一个内部“注册”自己)或者如果没有没有arguments的构造函数怎么办?

有没有更好的方法来做到这一点? 我不想创建一个“FileRegistry”class,它只保存每个 class 的文件路径。

但是,如果构建一个新的 class(我正在尝试加载的类型)有一些副作用(例如,在初始化时,class 在另一个内部“注册”自己)

Constructor#newInstance调用构造函数。 如果它有副作用,那些事情就会发生。 但请注意,理想情况下,构造函数应该只初始化 object 并且没有副作用(尤其是在构造函数完成之前不会泄漏对象/发布this -引用。

或者如果没有没有 arguments 的构造函数?

在这种情况下, getDeclaredConstructor()会抛出异常。 但是,您可以使用Class#getDeclaredConstructors获取所有构造函数。

但是,您可以在JsonSerializable的 Javadoc 中指定扩展JsonSerializable的类必须具有没有副作用的无参数构造函数。

虽然您可以在不使用Unsafe调用构造函数的情况下创建新实例,但应该避免这种情况,因为它会使变量未初始化,可能导致未来出现异常。

恕我直言,这看起来更像是您要加载的类上的注释@JsonSerializable(path="some.path")的用例。

代码可能如下所示:

// JsonSerializable.java
import java.lang.annotation.*;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface JsonSerializable {
    String path();
}

注释将在 class 上使用,如下所示:

// Options.java
@JsonSerializable(path="filepath.ending")
public class Options {
    private String example_property;
    private int example_property2;

    public Options() {
    }
}

然后读取注释的代码将是:

private static <T> T getNew(Class<T> tClass) throws Exception {
    JsonSerializable annotation = tClass.getAnnotation(JsonSerializable.class);
    System.out.println(annotation.path()); // Just to show how the path is read
    // here you would insert code to read the class the way you need
    return tClass.getDeclaredConstructor().newInstance();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM