2015-09-15 2 views
6

È possibile memorizzare riferimenti a un metodo getter utilizzando un Supplier?Enum con getter

Per essere utilizzare come che:

String value = myEnum.getValue(object) 

Non riesco a capire come scrivere senza errori di compilazione.

+0

Perché non 'valueOf()'? 'String result = myEnum.valueOf (oggetto); ' –

+0

Mi piacerebbe memorizzare un riferimento a un getter di un altro oggetto –

+2

Sicuramente, è possibile. I valori di 'enum' sono oggetti Java in modo che possano contenere tutto ciò che gli oggetti ordinari possono. Ma se stai parlando di getter vincolati a un'istanza, non sembra uno stile di codice consigliato e probabilmente un problema XY. – Holger

risposta

5

Non è molto difficile, se il tipo di ritorno per tutti i getter è la stessa. Si consideri il seguente classe POJO:

public static class MyPoJo { 
    final String foo, bar; 

    public MyPoJo(String foo, String bar) { 
     this.foo = foo; 
     this.bar = bar; 
    } 

    public String getFoo() { 
     return foo; 
    } 

    public String getBar() { 
     return bar; 
    } 

    public int getBaz() { 
     return 5; 
    } 
} 

allora possiamo avere tale enum:

public static enum Getters { 
    FOO(MyPoJo::getFoo), BAR(MyPoJo::getBar); 

    private final Function<MyPoJo, String> fn; 

    private Getters(Function<MyPoJo, String> fn) { 
     this.fn = fn; 
    } 

    public String getValue(MyPoJo object) { 
     return fn.apply(object); 
    } 
} 

e usarlo in questo modo:

System.out.println(Getters.FOO.getValue(new MyPoJo("fooValue", "barValue"))); // fooValue 

Tuttavia sarebbe problematico se si desidera tornare tipi diversi. In questo caso io suggerirei di usare classe normale con le istanze predefinite invece di enum:

public static final class Getters<T> { 
    public static final Getters<String> FOO = new Getters<>(MyPoJo::getFoo); 
    public static final Getters<String> BAR = new Getters<>(MyPoJo::getBar); 
    public static final Getters<Integer> BAZ = new Getters<>(MyPoJo::getBaz); 

    private final Function<MyPoJo, T> fn; 

    private Getters(Function<MyPoJo, T> fn) { 
     this.fn = fn; 
    } 

    public T getValue(MyPoJo object) { 
     return fn.apply(object); 
    } 
} 

utilizzo è lo stesso:

System.out.println(Getters.FOO.getValue(new MyPoJo("fooValue", "barValue"))); // fooValue 
System.out.println(Getters.BAZ.getValue(new MyPoJo("fooValue", "barValue"))); // 5 
6

Se ti prendo a destra e poi si vuole fare qualcosa di simile:

import java.util.function.DoubleSupplier; 

public class Test { 

    enum MathConstants { 

    PI(Test::getPi), E(Test::getE); 

    private final DoubleSupplier supply; 

    private MathConstants(DoubleSupplier supply) { 
     this.supply = supply; 
    } 

    public double getValue() { 
     return supply.getAsDouble(); 
    } 
    } 

    public static void main(String... args) { 
    System.out.println(MathConstants.PI.getValue()); 
    } 

    public static double getPi() { 
    return Math.PI; 
    } 

    public static double getE() { 
    return Math.E; 
    } 
}