简体   繁体   English

Java,只使用传入的参数泛型类型创建实例

[英]Java, create an instance by only using the passed parameter generic type

private static <T> String mapQueryResults(T objNew) {
    T obj = new T();
    ...
}

It gives me error "Cannot instantiate the type T".它给了我错误“无法实例化类型 T”。 How can I create an instance?如何创建实例? Thanks谢谢

You cannot do this.你不能做这个。 Type T could be any type, including interfaces and abstract classes, which cannot be instantiated themselves.类型T可以是任何类型,包括接口和抽象类,它们本身不能被实例化。 Even if a non-abstract class is passed, the empty constructor might not exist.即使传递了非抽象 class,空的构造函数也可能不存在。 If you wish to pass something to be able to create new instances of some class, then you could pass some factory class that creates these new instances for you through some method.如果您希望传递一些东西以创建一些 class 的新实例,那么您可以传递一些工厂 class 通过某种方法为您创建这些新实例。

When topics like these come up, my approach is "forget programming and think logically."当这些话题出现时,我的做法是“忘记编程,逻辑思考”。

The OP asked OP问

create an instance by only using the passed parameter generic type仅使用传递的参数泛型类型创建实例

Basically, you want a constructor to build a concrete thing based on something generic.基本上,您希望构造函数基于通用事物构建具体事物。 Is this possible in real life?这在现实生活中可能吗? Say that you need "something" built and you go to a builder and you tell the builder "I want you to build something for me" and provide no context, no additional information.假设您需要建造“某些东西”,并且您将 go 告诉建造者,然后您告诉建造者“我希望您为我建造一些东西”并且没有提供任何上下文,没有其他信息。 Is it realistic to expect that the builder will be able to build what you need?期望建造者能够建造你需要的东西是否现实? Of course the answer is no.答案当然是否定的。 Unless you specify in sufficient detail a description of what you want, the builder is not going to know what to build .除非你对你想要的东西进行了足够详细的描述,否则建造者不会知道要建造什么

T or "type", as others already mentioned, could be anything.正如其他人已经提到的那样, T或“类型”可以是任何东西。 If this was allowed by the language, you will most likely end up with nothing usable.如果语言允许这样做,那么您很可能最终没有可用的东西。 It would be like having T be dough.这就像让T成为面团一样。 Unless you specifically tell someone you want pizza, or bread, or flour tortillas, there is no way you can expect someone to make what you want if the only thing that is known is "dough."除非您明确告诉某人您想要披萨、面包或面粉玉米饼,否则如果唯一已知的东西是“面团”,您就无法期望有人做出您想要的东西。

Different "types" have different requirements for construction.不同的“类型”对施工有不同的要求。 In fact, some "types" cannot be built at all (they might have a private constructor).事实上,有些“类型”根本无法构建(它们可能有一个私有构造函数)。 Others the constructor is hidden behind static factory methods.其他的构造函数隐藏在 static 工厂方法后面。 In short, there are too many reasons why this is simply not possible.简而言之,这根本不可能的原因太多了。

All that said, you are not really wrong thinking that there should be a way where you can pass a set of different "types" of parameters to some function and end up with different kinds of concrete objects built.话虽如此,您认为应该有一种方法可以将一组不同的“类型”参数传递给一些 function 并最终构建不同种类的具体对象并没有错。 If that is what you are thinking, then what you need is a Design Pattern (or patterns) that will support this notion.如果这就是您的想法,那么您需要的是一个支持这个概念的设计模式(或多个模式)。

In the original Gang of Four book, you will find 5 CREATIONAL Design Patterns:在最初的 Gang of Four 书中,您会发现 5 种 CREATIONAL 设计模式:

  1. Abstract Factory - factory that builds family of things (ie a factory of factories)抽象工厂 - 构建事物系列的工厂(即工厂工厂)
  2. Builder - Builds the object in stages (typically when objects are too complex)构建器 - 分阶段构建 object(通常在对象过于复杂时)
  3. Factory Method - factory that build single type of object (or different things based on a common abstraction)工厂方法 - 构建单一类型 object 的工厂(或基于通用抽象的不同事物)
  4. Prototype - Creates a new object based on another object原型 - 基于另一个 object 创建一个新的 object
  5. Singleton - Ensures a single instance is created Singleton - 确保创建单个实例

Based on the little information in the original post, I believe the OP needs to implement either a Factory Method or possibly a Prototype pattern.基于原始帖子中的少量信息,我相信 OP 需要实现工厂方法或可能的原型模式。

You could change the method argument to accept a Supplier<T> constructor function, and pass in something like MyClass::new :您可以更改方法参数以接受Supplier<T>构造函数 function,并传入类似MyClass::new内容:

public class MyClass {
    public MyClass() {}
    public MyClass(String s) { ... }
}

public static void main(String[] args) {
    mapQueryResults(MyClass::new);
    mapQueryResults(() -> new MyClass("test"));
}   
    
private static <T> String mapQueryResults(Supplier<T> objNew) {
    T obj = objNew.get();
    ...
}

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

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