简体   繁体   English

如何从泛型方法实例化Java类

[英]how do I Instantiating a java class from generic method

I am trying to learn generics in Java. 我正在尝试学习Java中的泛型。 My question is can i instantiating a java class from generic method? 我的问题是我可以从泛型方法实例化Java类吗? I have a method like below 我有下面的方法

private  void  AddAction(ModelBuilding model,TableView table) {         
            table.getItems().add( new ModelBuilding());
        }

Here ModelBuilding() is my custom java class. 这里ModelBuilding()是我的自定义Java类。 When I am trying to make this method generic I am facing problem in instantiating ModelBuilding() class. 当我试图使该方法通用时,在实例化ModelBuilding()类时遇到了问题。 I tried like this and having a compile error. 我试图这样,并有一个编译错误。

private <E> void  AddAction(E mode,TableView table) {           
            table.getItems().add( new E());
        }

How I can make AddAction(E mode,TableView table) method generic? 如何使AddAction(E mode,TableView table)方法通用?

Since you are passing an instance of E to your method, you can create an instance of the same class via reflection: 由于将E的实例传递给方法,因此可以通过反射创建相同类的实例:

private <E> void AddAction(E mode,TableView table) {           
    table.getItems().add(mode.getClass().newInstance());
}

On the other hand, if you are not using the E instance passed to your method, it's enough to pass a Class<E> in order to create a new instance: 另一方面,如果您不使用传递给方法的E实例,则只需传递Class<E>即可创建新实例:

private <E> void AddAction(Class<E> clazz,TableView table) {           
    table.getItems().add(clazz.newInstance());
}

Either way, you'll have to catch some exceptions that may be thrown by newInstance() . 无论哪种方式,您都必须捕获newInstance()可能引发的一些异常。

Or, just add the instance passed to your method. 或者,只需添加传递给您的方法的实例。 The caller of the method will create the instance: 方法的调用者将创建实例:

private <E> void AddAction(E mode,TableView table) {           
    table.getItems().add(mode);
}

Did you try this 你尝试过这个吗

    private <E> void AddAction(E mode,TableView table)
    {           
       table.getItems().add( mode);
    }

As Eran mentioned using reflection to create an instance can trigger exceptions. 正如Eran所提到的,使用反射创建实例可以触发异常。 The javadoc says: Javadoc说:

Note that this method propagates any exception thrown by the nullary constructor, including a checked exception 请注意,此方法传播由nullary构造函数引发的任何异常,包括已检查的异常

So when using newInstance() you aren't aware of any possible exceptions at compile time. 因此,在使用newInstance()您在编译时不会发现任何可能的异常。

Furthermore you are limited to use the "nullary constructor". 此外,您只能使用“空构造函数”。 If you want to create an action which has no default constructor or want to use a parametrized constructor you would have to use a reflection call on a java.lang.reflect.Constuctor . 如果要创建没有默认构造函数的动作,或者想要使用参数化的构造函数,则必须在java.lang.reflect.Constuctor上使用反射调用。 This all is very fragile regarding code refactoring. 关于代码重构,这一切都是非常脆弱的。

An at least safer approach regarding refactoring is to use a factory method. 关于重构的至少更安全的方法是使用工厂方法。 Instead of passing Class<E> clazz to your method, you could pass in for example a Supplier<E> . 可以将例如Supplier<E>传递给您的方法,而不是将Class<E> clazz传递给您的方法。 Take a look at the following code: 看下面的代码:

private <E> void AddAction(Supplier<E> factory, TableView table) {
    E mode = factory.get();
    table.getItems().add(mode);
}

private void AddSimpleAction(TableView table) {
    AddAction(SimpleAction::new, table);
}

private void AddDateAwareAction(TableView table) {
    AddAction(() -> new DateAwareAction(new Date()), table);
}

private static class SimpleAction {
    // body
}

private static class DateAwareAction {

    private final Date date;

    public DateAwareAction(Date date) {
        this.date = date;
    }

    // body
}

If you refactor the constructor of DateAwareAction to use a parameter long dateTimeInMs you get a syntax error in the method AddDateAwareAction . 如果重构DateAwareAction的构造DateAwareAction以使用参数long dateTimeInMs则会在AddDateAwareAction方法中收到语法错误。 Using reflection to create an instnace this refactoring would stay unnoticed at compile time and would raise an exception at runtime. 使用反射来创建实例,这种重构在编译时不会被注意到,并且会在运行时引发异常。

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

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