2012-06-07 3 views
1

내가이런타임에 지정된 클래스 유형의 객체를 만드는 방법은 무엇입니까?

public void readAndInitialize(StringReader reader, Class className) 
    { 
    // Here, I want to to something like this - 

    // obj = new (object of the specified className) 

     obj.readAndInitialize(reader); 
    } 

같은 방법은 어떻게 자바에서이 작업을 수행 할 수 있다고 가정? 귀하의 예제에서 당신이 Class 개체로 클래스 이름을 전달하는, 그래서 당신이 할 수

답변

4

누구나 Class.forName("com.myorg.MyClass"); 메서드와 관련된 newInstance() 메서드를 빠르게 지적하고 있지만 매개 변수를 사용하지 않는 기본 생성자 만 호출한다는 점을 기억해야합니다.

클래스의 특정 생성자를 호출해야하는 경우 반사를 사용하여 올바른 생성자를 찾아서 호출해야합니다.

import java.lang.reflect.Constructor; 
import java.lang.reflect.Type; 
import static java.lang.System.out; 

public class ConstructorSift { 
    public static void main(String... args) { 
    try { 
     Class<?> cArg = Class.forName(args[1]); 

     Class<?> c = Class.forName(args[0]); 
     Constructor[] allConstructors = c.getDeclaredConstructors(); 
     for (Constructor ctor : allConstructors) { 
     Class<?>[] pType = ctor.getParameterTypes(); 
     for (int i = 0; i < pType.length; i++) { 
      if (pType[i].equals(cArg)) { 
      out.format("%s%n", ctor.toGenericString()); 

      Type[] gpType = ctor.getGenericParameterTypes(); 
      for (int j = 0; j < gpType.length; j++) { 
       char ch = (pType[j].equals(cArg) ? '*' : ' '); 
       out.format("%7c%s[%d]: %s%n", ch, 
         "GenericParameterType", j, gpType[j]); 
      } 
      break; 
      } 
     } 
     } 

     // production code should handle this exception more gracefully 
    } catch (ClassNotFoundException x) { 
     x.printStackTrace(); 
    } 
    } 
} 

은 모든 구성자를 나열합니다 (and a tutorial is available here). 당신이 원하는 생성자를 찾았 으면

, 당신은 다시 from the tutorial about reflection 그래서

import java.lang.reflect.Constructor; 
import java.lang.reflect.Field; 
import java.lang.reflect.InvocationTargetException; 
import java.util.HashMap; 
import java.util.Map; 
import java.util.Set; 
import static java.lang.System.out; 

class EmailAliases { 
    private Set<String> aliases; 
    private EmailAliases(HashMap<String, String> h) { 
    aliases = h.keySet(); 
    } 

    public void printKeys() { 
    out.format("Mail keys:%n"); 
    for (String k : aliases) 
     out.format(" %s%n", k); 
    } 
} 

public class RestoreAliases { 

    private static Map<String, String> defaultAliases = new HashMap<String, String>(); 
    static { 
    defaultAliases.put("Duke", "[email protected]"); 
    defaultAliases.put("Fang", "[email protected]"); 
    } 

    public static void main(String... args) { 
    try { 
     Constructor ctor = EmailAliases.class.getDeclaredConstructor(HashMap.class); 
     ctor.setAccessible(true); 
     EmailAliases email = (EmailAliases)ctor.newInstance(defaultAliases); 
     email.printKeys(); 

     // production code should handle these exceptions more gracefully 
    } catch (InstantiationException x) { 
     x.printStackTrace(); 
    } catch (IllegalAccessException x) { 
     x.printStackTrace(); 
    } catch (InvocationTargetException x) { 
     x.printStackTrace(); 
    } catch (NoSuchMethodException x) { 
     x.printStackTrace(); 
    } 
    } 
} 

처럼 호출 할 수 있습니다.

2

참고 :

className.newInstance(); 

하지만 의심 당신이 같이 클래스 이름을 전달하는 방법을 찾고 있다는 것을 String는,이 경우 절차는 (여기 classNameString입니다)입니다 : 모두 호출에 의해 던져 Exceptions을 처리하기 위해 당신은 또한 필요합니다

Class class = Class.forName(className()); 
Object obj = class.newInstance(); 

참고.

이것은 가장 간단한 경우이며 예를 들어 특정 생성자.

클래스에 대해 the docs을 참조하십시오.

1
public void readAndInitialize(StringReader reader, String className) //className changed to String 
    { 
    // Here, I want to to something like this - 
    // obj = new (object of the specified className) 

     //try this: 
     Class myclass = Class.forName(className); 
     Object obj = myclass.newInstance(); 

     obj.readAndInitialize(reader); 
    } 
1

질문을 올바르게 이해하면. 지정된 클래스의 객체는 다음과 같이 작성해야합니다 :

if (yourClass != null) { 
    Object yourObject = null; 
    try { 
     yourObject = yourClass.newInstance(); 
    } catch (InstantiationException e) { 
     LOGGER.error("", e);    
    } catch (IllegalAccessException e) { 
     LOGGER.error("", e); 

    } 
} 
0

당신은) 당신이에 Class.newInstance를 (사용하여 원하는 것을 할 수 있습니다 또는는 Constructor.newInstance (단, 인수 생성자)(). 작업 예제는 here을 참조하십시오.

0

이미 또는 클래스 명에 불과 문자열 객체를 얻는 경우에 따라, 나는 다음을 수행합니다 :

  1. 이 클래스 이름의 문자열로, 반사를 이용하여, 상기 한 바와 같은 개체를 인스턴스화를; 이미 개체를 얻을 경우, 당신은
  2. 개체가
  3. 당신이 한 단계 체크 클래스 개체를 캐스팅 instanceof를 통해 공개 방법 readAndAnalyze (...)를 제공하는 클래스 또는 인터페이스에서 상속 확인이 단계를 건너 뛸 수 있습니다 위의 instanceof를 통해
관련 문제