Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于枚举类型创建对象的Java方法_Java_Design Patterns_Enums_Dynamic Class Creation - Fatal编程技术网

基于枚举类型创建对象的Java方法

基于枚举类型创建对象的Java方法,java,design-patterns,enums,dynamic-class-creation,Java,Design Patterns,Enums,Dynamic Class Creation,我的课是这样的: class X {} class Y extends X {}; class Z extends X {}; 每个子类(id+类)都有一个枚举: 然后我使用它们如下: X parseFromID(int id) { for (Type v : Type.values()) { if (v.id == id) { return v.createInstance(); } } } 它工作正常,但我想知道这是否是一种基于整数id创建

我的课是这样的:

class X {}
class Y extends X {};
class Z extends X {};
每个子类(id+类)都有一个枚举:

然后我使用它们如下:

X parseFromID(int id) {
   for (Type v : Type.values()) {
     if (v.id == id) {
        return v.createInstance();
     }
   }
}
它工作正常,但我想知道这是否是一种基于整数id创建数据的Java ist方法?有什么不好的东西应该找吗

有没有一种方法可以在没有冗长的if-else条件的情况下强制将类传递给X类型的are?当我有大量的子类时想想


为什么要处理整数ID


我正在编写某种解析器,因此我需要将从某处获取的整数id转换为适当的对象。

这里确实没有理由使用反射。抛出异常也是一种糟糕的做法,如果不使用反射,就不必处理反射异常。你可以这么做

enum Type {
    Y_TYPE(1) {
        @Override
        public X createInstance() {
            return new Y();
        }
    }, Z_TYPE(2) {
        @Override
        public X createInstance() {
            return new Z();
        }
    };

    private int id;

    private Type(int id) { 
        this.id = id; 
    }

    public abstract X createInstance();
}
这也很有帮助,因为它不会强制每个子类都有一个公共的无参数构造函数,如果可能的话,还允许返回相同的X或Y实例

如果您担心匿名类定义的冗长性,如果您使用的是Java 8,则可以将其替换为lambdas:

import java.util.function.Supplier;

enum Type {
    Y_TYPE(1, X::new), Z_TYPE(2, Y::new);

    private int id;
    private Supplier<X> supplier;

    private Type(int id, Supplier<X> supplier) {
        this.id = id;
        this.supplier = supplier;
    }

    public X createInstance() {
        return supplier.get();
    }
}
导入java.util.function.Supplier;
枚举类型{
Y_类型(1,X::new)、Z_类型(2,Y::new);
私有int-id;
私人供应商;
私有类型(int id,供应商){
this.id=id;
此项。供应商=供应商;
}
public X createInstance(){
返回供应商。get();
}
}
有没有一种方法可以在没有冗长的if-else条件的情况下强制将类传递给X类型的are

是的,您可以使用泛型来限制类。将构造函数更改为:

public Type(int id, Class<? extends X> c) { this.id = id; this.c = c; }

公共类型(int-id,Class使用工厂和映射更具学术性:

import java.util.HashMap;
import java.util.Map;

interface Factory<T> {

    T createInstance();
}

class X {/**/}
class Y extends X {/**/}
class Z extends X {/**/}

class Factories {

   static Map<Integer, Factory<?>> factories = new HashMap<>();
   static {
      factories.put( 1, X::new );
      factories.put( 2, Y::new );
      factories.put( 3, Z::new );
   }

   @SuppressWarnings("unchecked")
   static <T> Factory<T> get( int id ) {
      return (Factory<T>)factories.get( id );
   }
}

public class Main {

   static void main( String[] args ) {
      final Factory<X> fx = Factories.get( 1 );
      final X x = fx.createInstance();
      final Factory<Y> fy = Factories.get( 2 );
      final Y y = fy.createInstance();
      final Factory<Z> fz = Factories.get( 3 );
      final Z z = fz.createInstance();
   }
}
import java.util.HashMap;
导入java.util.Map;
接口工厂{
T createInstance();
}
类X{/**/}
类Y扩展了X{/**/}
类Z扩展了X{/**/}
阶级工厂{

静态MapI考虑一下这个问题,但是如果我有大量的子类,它很快就会变成一个很长的代码,对吗?它有点冗长,但不会太长。请参阅我编辑过的答案,以获得一个不太冗长的解决方案。第二个版本看起来与我的版本没有太大的不同,主要的优点是什么?优点就在答案中。阅读它。没有ex概念、类型安全、实现供应商的灵活性、更好的性能我们如何满足通过参数化构造函数创建对象的要求?
import java.util.HashMap;
import java.util.Map;

interface Factory<T> {

    T createInstance();
}

class X {/**/}
class Y extends X {/**/}
class Z extends X {/**/}

class Factories {

   static Map<Integer, Factory<?>> factories = new HashMap<>();
   static {
      factories.put( 1, X::new );
      factories.put( 2, Y::new );
      factories.put( 3, Z::new );
   }

   @SuppressWarnings("unchecked")
   static <T> Factory<T> get( int id ) {
      return (Factory<T>)factories.get( id );
   }
}

public class Main {

   static void main( String[] args ) {
      final Factory<X> fx = Factories.get( 1 );
      final X x = fx.createInstance();
      final Factory<Y> fy = Factories.get( 2 );
      final Y y = fy.createInstance();
      final Factory<Z> fz = Factories.get( 3 );
      final Z z = fz.createInstance();
   }
}