Enums und Vererbung

Cola_Colin

Top Contributor
Hi,
gegeben folgendes Enum:
Java:
	public enum Product {
		client(1), server(2);
		private Product(int i) {
			id = i;
		}
		private int id;
		
		public int getId() {
			return id;
		}
		
		public static Product byId(int id) {
			for (Product p: values()) {
				if (p.getId() == id) {
					return p;
				}
			}
			throw new IllegalArgumentException("unknown id");
		}
	}

Ich habe noch eine Reihe weitere solcher Enums, alle mit einem byId(int id). Die Methode sieht immer gleich aus und es wäre toll, sie in eine Basisklasse auszulagern. Aber enums können nur Interfaces implementieren. Mein Versuch ein Interface mit getId() zu machen und eine statische Hilfsmethode zu schreiben scheitert daran, dass ich dann auf values nicht zugreifen kann.

Eine Lösung per Reflection geht:
Java:
	@SuppressWarnings("unchecked")
	private static <T> T getById(Class<T> t, int id) {
		try {
			Method values = t.getMethod("values");
			Method getId = t.getMethod("getId");
			for (T x: (T[])values.invoke(null)) {
				if (((Integer)getId.invoke(x)) == id) {
					return x;
				}
			}
			throw new IllegalArgumentException();
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		}
	}

Aber geht das auch ohne diesen Umweg und eventuell als Instanzmethode von den Enums?
 
Nicht wirklich die Lösung, es müssten alle Enums in einem gruppiert werden müssten:
Java:
public enum Product {

        CLIENT(1) {
            int myMethod() { return 123; }
        },

        SERVER(2) {
            int myMethod() { return 432; }
         };

        private int id;

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

        public int getId() {
            return id;
        }

        abstract int myMethod();
        
        public static Product byId(int id) {
            for (Product p: values()) {
                if (p.getId() == id) {
                    return p;
                }
            }
            throw new IllegalArgumentException("unknown id");
        }
    }
 
Hmm ja, das Problem, dass ich nicht an values() rankomme bleibt. values scheint nicht in Enum definiert zu sein, sondern taucht von irgendwo auf, wenn man enums definiert?!
Beispiel:
Java:
public class EnumStuff {
	
	public interface GetId {
		int getId();
	}
	
	public static <T extends Enum<T> & GetId> T getById(T clazz, int id) {
		// kein zugriff auf values ...
	}
	
	public enum Product implements GetId{
		client(1), server(2);
		
		private Product(int id) {
			this.id = id;
		}
		
		private int id;

		@Override
		public int getId() {
			return id;
		}
	}
	
	public enum PaymentType implements GetId {
		weekly(0), monthly(1), yearly(2);
		
		private PaymentType(int id) {
			this.id = id;
		}
		
		private int id;
		
		@Override
		public int getId() {
			return id;
		}
	}
}
 
Reflection im ersten Post ist unnötig, wie gesagt wurde, gehen doch Interface?
für das Enum-Array gibt es gar eine feste Class-Methode, values() per Reflection ist unschön
Java:
public class Test {
    public static void main(String[] args)  {
        getById(Product2.class,4); // geht nicht, kein Enum
        getById(Product.class,4);
    }

    private static <T extends Enum & A>T getById(Class<T> t, int id)  {
        for (T x : t.getEnumConstants())     {
            if (x.getId() == id)  {
                return x;
            }
        }
        return null;
    }
}


interface A {
    public int getId();
}

class Product2  implements A {
    public int getId()  {
        return 0;
    }
}


enum Product implements A {
    client(1), server(2);
    private Product(int i)   {
        id = i;
    }

    private int id;

    public int getId()  {
        return id;
    }

}

----

wenn die natürlich vergebenen Ids der Enums helfen, 0, 1, 2, 3, .oridinal(),
dann gar direkt der Index im Enum-Array,


-----

@Gregorrr
der Sinn für eine abstrakte Methode ist hier nicht ganz erkennbar, sollen die verschieden implementiert werden können?
wenn nur ein jeweils anderer Wert zurückgegeben wird, reicht normale Methode + Attribut, Wert im Konstruktor,
wie vollkommen parallel für Id ja vorgemacht daneben steht
 
Zuletzt bearbeitet von einem Moderator:

Zurück
Oben