Java에서 클래스를 매개 변수로 어떻게 전달합니까?


136

Java에서 클래스를 매개 변수로 전달하고 해당 클래스에서 일부 메소드를 실행하는 방법이 있습니까?

void main()
{
    callClass(that.class)
}

void callClass(???? classObject)
{
    classObject.somefunction
    // or 
    new classObject()
    //something like that ?
}

Google Web Toolkit을 사용하고 있으며 반영을 지원하지 않습니다.

답변:


130
public void foo(Class c){
        try {
            Object ob = c.newInstance();
        } catch (InstantiationException ex) {
            Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

리플렉션을 사용하여 메소드를 호출하는 방법

 import java.lang.reflect.*;


   public class method2 {
      public int add(int a, int b)
      {
         return a + b;
      }

      public static void main(String args[])
      {
         try {
           Class cls = Class.forName("method2");
           Class partypes[] = new Class[2];
            partypes[0] = Integer.TYPE;
            partypes[1] = Integer.TYPE;
            Method meth = cls.getMethod(
              "add", partypes);
            method2 methobj = new method2();
            Object arglist[] = new Object[2];
            arglist[0] = new Integer(37);
            arglist[1] = new Integer(47);
            Object retobj 
              = meth.invoke(methobj, arglist);
            Integer retval = (Integer)retobj;
            System.out.println(retval.intValue());
         }
         catch (Throwable e) {
            System.err.println(e);
         }
      }
   }

참조


어떻게 기본 생성자 또는 해당 클래스의 일부 메소드를 시작합니까?

죄송합니다. Google 웹 툴킷을 사용하는 것을 잊어 버렸습니다. Google 웹 툴킷을 사용하는 메신저이며 리플렉션을 지원하지 않습니다.

1
여기여기 또한
Jigar 조시

나는 철학에 대해 이야기하고 싶다! 클래스가 Java의 데이터 유형입니까?
Milad Rahimi

40
public void callingMethod(Class neededClass) {
    //Cast the class to the class you need
    //and call your method in the class
    ((ClassBeingCalled)neededClass).methodOfClass();
}

메소드를 호출하려면 다음과 같이 호출하십시오.

callingMethod(ClassBeingCalled.class);

asker는 클래스의 생성자를 사용하기를 원했습니다. 쉬운 일이 아니며 아무도 여기에서 다루지 않습니다. 이 게시물은 stackoverflow.com/questions/234600/… 옵션을 제공합니다 (허용 된 답변이 작동하지 않기 때문에 모든 의견 읽기) . 그래도 꽤 지저분하고 컴파일러 경고는 사람들이 Java로 이것을하지 않기를 원한다고 제안합니다. 파이썬에서 훨씬 더 쉽습니다
:)

9

그것을 받아 들일 방법을 만드십시오.

public <T> void printClassNameAndCreateList(Class<T> className){
    //example access 1
    System.out.print(className.getName());

    //example access 2
    ArrayList<T> list = new ArrayList<T>();
    //note that if you create a list this way, you will have to cast input
    list.add((T)nameOfObject);
}

방법을 호출

printClassNameAndCreateList(SomeClass.class);

클래스 유형을 제한 할 수도 있습니다. 예를 들어, 이것은 내가 만든 라이브러리의 메소드 중 하나입니다.

protected Class postExceptionActivityIn;

protected <T extends PostExceptionActivity>  void  setPostExceptionActivityIn(Class <T> postExceptionActivityIn) {
    this.postExceptionActivityIn = postExceptionActivityIn;
}

자세한 내용을 보려면 Reflection 및 Generics를 검색하십시오.


4

사용하다

void callClass(Class classObject)
{
   //do something with class
}

A Class도 Java 객체이므로 해당 유형을 사용하여 참조 할 수 있습니다.

공식 문서 에서 자세한 내용을 읽으십시오 .


2

이런 종류의 일은 쉽지 않습니다. 정적 메소드를 호출하는 메소드는 다음과 같습니다.

public static Object callStaticMethod(
    // class that contains the static method
    final Class<?> clazz,
    // method name
    final String methodName,
    // optional method parameters
    final Object... parameters) throws Exception{
    for(final Method method : clazz.getMethods()){
        if(method.getName().equals(methodName)){
            final Class<?>[] paramTypes = method.getParameterTypes();
            if(parameters.length != paramTypes.length){
                continue;
            }
            boolean compatible = true;
            for(int i = 0; i < paramTypes.length; i++){
                final Class<?> paramType = paramTypes[i];
                final Object param = parameters[i];
                if(param != null && !paramType.isInstance(param)){
                    compatible = false;
                    break;
                }

            }
            if(compatible){
                return method.invoke(/* static invocation */null,
                    parameters);
            }
        }
    }
    throw new NoSuchMethodException(methodName);
}

업데이트 : 잠깐, 질문에서 gwt 태그를 보았습니다. GWT에서는 리플렉션을 사용할 수 없습니다


1

나는 당신이 무엇을 성취하려고하는지 잘 모르겠지만, 수업을 통과하는 것이 실제로 해야하는 것이 아닐 수도 있습니다. 대부분의 경우 이와 같은 클래스를 처리하는 것은 일부 유형의 팩토리 패턴 내에 쉽게 캡슐화되며 인터페이스를 통해 사용됩니다. 다음은 해당 패턴에 관한 수십 가지 기사 중 하나입니다. http://today.java.net/pub/a/today/2005/03/09/factory.html

팩토리 내에서 클래스를 사용하는 것은 다양한 방법으로 달성 될 수 있으며, 가장 중요한 것은 필요한 인터페이스를 구현하는 클래스 이름이 포함 된 구성 파일을 갖는 것입니다. 그런 다음 팩토리는 클래스 경로에서 해당 클래스를 찾아 지정된 인터페이스의 객체로 구성 할 수 있습니다.


0

말했듯이 GWT는 리플렉션을 지원하지 않습니다. 리플렉션 대신 지연 바인딩 또는 gwt 레이어의 리플렉션 지원을 위해 gwt-ent 와 같은 타사 라이브러리를 사용해야 합니다.



-1

OP는 리플렉션을 지원하지 않는 GWT를 사용한다고 분명히 밝혔습니다
Knarf

2
내 대답 후 오랫동안 질문이 편집되었습니다. 원래 질문에는 그 힌트가 포함되어 있지 않습니다. 받아 들여진 대답은 또한 반성을 언급하고 있습니다.
Marcus Gründler

-1

paramater로서의 클래스. 예.

세 가지 수업 :

class TestCar {

    private int UnlockCode = 111;
    protected boolean hasAirCondition = true;
    String brand = "Ford";
    public String licensePlate = "Arizona 111";
}

-

class Terminal {

public void hackCar(TestCar car) {
     System.out.println(car.hasAirCondition);
     System.out.println(car.licensePlate);
     System.out.println(car.brand);
     }
}

-

class Story {

    public static void main(String args[]) {
        TestCar testCar = new TestCar();
        Terminal terminal = new Terminal();
        terminal.hackCar(testCar);
    }

}

터미널 메소드 hackCar ()에서 TestCar 클래스를 매개 변수로 사용하십시오.


1
아니, 그것은 TestCar의 인스턴스를 가지고있다
towc
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.