2015-11-20 3 views
2

У меня есть этот фрагмент кода Java:Если класс существует, вызов конструктора

try { 
    Class.forName(command); 
} catch (ClassNotFoundException ex) {  
} 

, где «команда» является строкой, которая вводится вручную во время выполнения. Ради вопроса, допустим, пользователь вводит «Foo».

Он проверяет, существует ли класс с именем Foo. То, что я хочу сделать после проверки, - это вызов метода из Foo.

Foo.execute(); 

Как это сделать, не делая специальный случай «если» для каждого из моих классов? Есть ли способ использовать что-то вроде псевдонима ($ command) .execute(), где $ command будет (в данном случае) моим Foo Class?

+2

HTTP: // StackOverflow.com/questions/2467544/invoking-a-static-method-using-reflection –

+0

Если вы хотите ссылаться на классы, которые вы можете вводить как единый объект, я бы сказал, что используйте суперкласс. Таким образом, каждый класс, который может быть введен, расширяет или реализует InputClazz.class или что-то. –

+0

Привет, Пожалуйста, взгляните на команду Pattern. Просто сохраните свои команды в HashMap . : http://www.javaworld.com/article/2077569/core-java/java-tip-68--learn-how-to-implement-the-command-pattern-in-java.html – Marcinek

ответ

2

Мой первый инстинкт был бы для любого класса, который вы хотите, чтобы быть в состоянии выполнить из имя будет заключаться в том, чтобы каждый из них реализовал общий интерфейс.

Пример:

public Interface InputClazz { 
    public void execute(); 
} 

public class Foo implements InputClazz { 
    public void execute() { 
    //do Stuff 
    } 
} 

public class Bar implements InputClazz { 
    public void execute() { 
    //do Stuff 
    } 
} 

Как вызвать:

try { 
    Class clazz = Class.forName(command); 
    InputClazz input = (InputClazz) clazz.newInstance(); 
    input.execute(); 
} catch (ClassNotFoundException ex) {  
} 

Вы можете затем ввести либо Foo или бар, и код будет работать бетон выполнить методы класса.

0

Это печатает «Hello World»

private static void call(String className, String methodName) { 
    try { 
     Class<?> clazz = Class.forName(className); 
     Object instance = clazz.newInstance(); 
     Method method = clazz.getMethod(methodName); 
     method.invoke(instance); 
    } catch (InstantiationException e) { 
     e.printStackTrace(); 
    } catch (IllegalAccessException e) { 
     e.printStackTrace(); 
    } catch (ClassNotFoundException e) { 
     e.printStackTrace(); 
    } catch (NoSuchMethodException e) { 
     e.printStackTrace(); 
    } catch (SecurityException e) { 
     e.printStackTrace(); 
    } catch (IllegalArgumentException e) { 
     e.printStackTrace(); 
    } catch (InvocationTargetException e) { 
     e.printStackTrace(); 
    } 
} 

static class Foo { 
    public void foo() { 
     System.out.println("Hello World"); 
    } 
} 

public static void main(String[] args) { 
    call(Foo.class.getName(), "foo"); 
} 

Единственное, не так приятно, что вы должны использовать полное имя класса. Поэтому вместо Foo это, скорее всего, что-то уродливое, как com.mycompany.something.Foo. Или вам действительно нужно убедиться, что эти классы не имеют пакета.

0

Я думаю, что у Наппы есть хороший практический ответ. Если вы хотите быть немного фаворитом, вы можете проверить свой класс на членство в иерархии с помощью isAssignableFrom() по методу Class.

Код ниже использует встроенную иерархию (StringBuilder реализует интерфейс CharSequence). Когда он находит класс типа CharSequence, он бросает класс, а затем называет length().

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

Обратите внимание, что этот код по-прежнему бросает ClassNotFoundExcpetion, если вы неправильно назовете имя класса. Вы все равно должны поймать это исключение.

public class ReflectionSubclassing 
{ 

    public static void main(String[] args) 
      throws ClassNotFoundException, InstantiationException, 
      IllegalAccessException 
    { 
     getDoubleValue("java.lang.StringBuilder"); 
     getDoubleValue("javax.swing.JButton"); 
    } 

    private static void getDoubleValue(String className) 
      throws ClassNotFoundException, InstantiationException, 
      IllegalAccessException 
    { 
     Class<?> tempClass = Class.forName(className); 
     if(java.lang.CharSequence.class.isAssignableFrom(tempClass)) { 
     Object charSeq = tempClass.newInstance(); 
     CharSequence cs = (java.lang.CharSequence)charSeq; 
     System.out.println(cs.length()); 
     } else 
     System.out.println("nope"); 
    } 
} 

Пример вывода Код:

run: 
0 
nope 
BUILD SUCCESSFUL (total time: 0 seconds) 
Смежные вопросы