2017-02-20 6 views
0

У меня есть два простых класса и используйте шаблон отражения для метода invoke. Я хочу написать программирование модуля. Предположим, у нас есть таблица в базе данных, которые держат название модулей:Как использовать потребитель и поставщик вместо Reflection in java 8

Id moduleName methodName ClassName    active 
1  sample  a   com.examle.sample  true 
2  SMS  sendSMS  com.example.SMS   false 
3  Email  sendEmail com.example.Email  false 
... ...   ...      ... 

Когда активна правда модуль должен быть activated.So, когда я пишу программу и компилировать, что я не хотел снова собрать всю MyApp. Поэтому я использую шаблон отражения для вызова модуля. см. коды.

public class Sample { 
    public void a() { 
     System.out.println("Call Method a"); 
    } 
} 
public class SMS { 
    public void sendSMS(String str) { 
     System.out.println("send SMS ok"); 
    } 
} 
public class Email { 
    public void sendEmail(String str) { 
     System.out.println("send Email ok"); 
    } 
} 
public class SampleMainClass { 
    public static void main(String[] args) { 

      //coonect to database and fetch all record in tables 
     while(record.next){ 
      if (record.getActive()){   
      Object o = Class.forName(record.getClssName()).newInstance() ; 
      Method method = o.getClass().getDeclaredMethod(record.getMethodName()); 
      method.invoke(o); 
      }        
     } 
    } 

выход

Call Method a 

Так я слышал в Java 8, картина отражения принизить и вместо того, что мы можем использовать потребитель и поставщик.

Как использовать потребитель и поставщик вместо Reflection in java 8?

Спасибо.

+0

Ваш пример не является хорошим вариантом использования, поскольку в первую очередь не имеет смысла использовать отражение. Попробуйте представить пример, демонстрирующий * потребность * для отражения, а не * как * он используется. – shmosel

ответ

4
public class Q42339586 { 

    static class Sample { 
     void a() { System.out.println("a() called"); } 
     void b() { System.out.println("b() called"); } 
    } 

    static <T> void createInstanceAndCallMethod(
      Supplier<T> instanceSupplier, Consumer<T> methodCaller) { 
     T o = instanceSupplier.get(); 
     methodCaller.accept(o); 
    } 

    public static void main(String[] args) { 
     createInstanceAndCallMethodJava8(Sample::new, Sample::a); 
    } 

} 

Здесь createInstanceAndCallMethod делает то, что делается в основной() метод, но он принимает параметры вместо.

А Supplier используется для создания нового экземпляра, а Consumer используется для вызова определенного метода в этом экземпляре. В этом примере обе ссылки на методы передаются как оба параметра. Вместо этого вы также можете использовать лямбда-выражения и вместо этого писать () -> new Sample() и o -> o.a(). Для получения дополнительной информации см. this official tutorial part.

Преимущества перед отражением очевидны:

  1. Вы не можете попросить createInstanceAndCallMethod создать экземпляр класса, который не существует.
  2. Вы не можете запросить createInstanceAndCallMethod вызов метода, который не существует в определенном классе.
  3. В результате вы не должны иметь дело с каким-либо проверенным Исключением.

Конечно, это работает только тогда, когда в каком-либо месте в коде известен фактический класс и метод, например. невозможно прочитать имя класса и метода из файла свойств, а затем использовать механизмы Java 8 для безопасного создания экземпляра и вызова определенного метода.

+0

Вероятно, есть преимущество в производительности. – shmosel

+0

Не затворить или что-то еще, но «например, невозможно прочитать имя класса и метода из файла свойств, а затем использовать механизмы Java 8, чтобы безопасно создать экземпляр и вызвать конкретный метод». Разве это не совсем то, что (отредактированная версия) вопроса aks? Как это может быть принятым ответом? Это не отвечает на то, как динамически вызывать данный метод данного класса, только из известных методов и классов. – GPI

+0

Спасибо. «невозможно прочитать имя класса и метода из файла свойств», так как это сделать для программирования модулей в java 8? – user6920966

2

Consumer и Supplier - это функциональные интерфейсы и они не относятся к отражению.

Это разные вещи.

Таким образом, я слышал в java 8, картина отражения не соответствует действительности, и вместо этого мы можем использовать потребителя и поставщика.

Неверная информация.

+0

Функциональные интерфейсы и lambdas позволяют использовать сжатый динамический метод, который не был возможен до Java 8 без использования отражения. Я думаю, что это то, к чему стремится OP, хотя представленный пример затрудняет демонстрацию. – shmosel

+0

«Функциональные интерфейсы позволяют методам быть сжатыми», это возможно из-за ссылок на методы и лямбда-выражения. Но что не так в моем ответе? Мы можем создавать те же интерфейсы «Поставщик» и «Потребитель» и использовать их в Java 7. Пожалуйста, объясните. – Vusal

+0

Ключ * лаконично *. В Java 7 нет эквивалента для класса Class :: method, без отражения. – shmosel