2011-11-02 5 views
7

그래서 GroupManager와 같은 몇 가지 'Manager'클래스가 있습니다. 이 모든 관리자들은 싱글 톤입니다.Java generics, singletons 및 static methods

인스 턴싱이 방법을 사용 : 내가 생각하고

private static GroupManager groupManager = null; 

private GroupManager() 
{ 

} 

public static GroupManager Instance() 
{ 
    if (groupManager == null) 
    { 
     groupManager = new GroupManager(); 
    } 
    return groupManager; 
} 

나는 그들이 복사 방법을 많이 가지고 일부 상속을 사용하기 시작한다.

각 Manager의 Instance() 메소드는 동일합니다.

그래서 상속 난 (분명히)이 작업을 수행 할 수 있습니다

public class Manager<E> 
{ 
    private static E instance = null; 

    public static E Instance() 
    { 
     if (instance == null) 
     { 
      instance = new E(); 
     } 
     return instance; 
    } 

} 

내 생각 :

GroupManager extends Manager 

이 가능, 무언가 같이 모든 관리자에 대해 같은 인스턴스 메서드를 사용하여 제네릭을 사용하는 것입니다 그게 말이 되네 :)

그런 다음 GroupManager.Instance()를 정상적으로 수행 할 것입니다.

+1

자바 제네릭은 어떠한 방식에 사용을 놓치지 않는 경우에만 미세 있도록 정적 컨텍스트에서 사용되는 C++ 템플릿과 동일! 가자! Java Generic을 사용하여 객체를 할당 할 수는 없습니다 (즉, 새로 호출). "Java Type Erasure"에 대한 Google 검색을 시도하십시오. – DwB

+0

관련 : http://stackoverflow.com/questions/1927789/why-should-care-that-java-doesnt-have-reified-generics – BalusC

+0

관리자 E is a 제네릭 형식에 대한 참조. 런타임에만 알 수있는 유형의 객체를 할당하도록 클래스를 설정하는 간단한 방법은 없습니다. Reid Mac의 대답은 제가 시도 할 것입니다. – DwB

답변

9

제네릭과 통계학이 어떻게 작동하는지 이해하지 못합니다. 클래스 매니저를 인스턴스화하지 않고 호출 할 수있는 정적 필드 또는 메소드 (예 : "instance"또는 instance())가있는 경우 JVM (및 컴파일러 짝수)이 예상되는 E 유형을 알 수있는 방법은 무엇입니까? 있다?

지배인 및 AreaManager 모두 관리자 클래스의 getInstance() 정적 메소드 갖는다 유일 관리자

연장 :

public class Manager { 

     private static Map<Class<? extends Manager>,Manager> INSTANCES_MAP = new java.util.HashMap<Class<? extends Manager>, Manager>(); 

//Also, you will want to make this method synchronized if your application is multithreaded, 
//otherwise you mihgt have a race condition in which multiple threads will trick it into 
//creating multiple instances 
     public static <E extends Manager> E getInstance(Class<E> instanceClass) throws InstantiationException, IllegalAccessException { 
      if(INSTANCES_MAP.containsKey(instanceClass)) { 
       return (E) INSTANCES_MAP.get(instanceClass); 
      } else { 
       E instance = instanceClass.newInstance(); 
       INSTANCES_MAP.put(instanceClass, instance); 
       return instance; 
      } 
     } 
    } 
+1

그래,하지만 싱글 톤을 구현하는 아이디어에는 전혀 효과가 없을 것입니다. '클래스'에서 인스턴스로 맵과 같이 끔찍하게 왜곡 된 구조가 필요합니다. –

+0

+1, 그건 사실입니다. 제가 그러한 관찰을 추가해야하는지 아닌지 생각해 보았습니다. (저는 제네릭과 통계학의 기본 개념을 먼저 이해해야 만 이런 식으로 사용되기 전에 이해할 필요가 없습니다.) 그러나 당신은 좋은 지적을합니다. 더 나아가 E extends RootOfIheritanceChainClass와 같은 기본 클래스로 제네릭 E 유형을 제한 할 수 있습니다. –

+0

나는 다소 잃어버린 LOL이다, 나는 그냥 가야한다. 기본적으로 새로운 매니저마다 새로운 Instance() 메소드가 필요하다. – Metalstorm

2

여기

는 G_H의 제안에 따라, 예입니다 아니, 작동하지 않을거야. Java는 유형 검사를 위해 컴파일시 generics를 사용하지만 런타임에 유형 매개 변수와 관련된 정보를 유지하거나 추가 클래스를 생성하지 않습니다.

Manager<E>을 해당 유형 매개 변수 E으로 선언하면 실제 인스턴스에서만 역할을 수행하게됩니다. GroupManager extends Manager<String>과 같은 서브 클래스를 가질 수도 있지만, 그것은 마술처럼 다양한 정적 메소드를 생성하지는 않습니다.

정적 메서드 및 멤버는 인스턴스가 아닌 클래스에 속합니다. 따라서 인스턴스를 입력하기 위해 제네릭을 사용하려고 시도하는 것은 불가능합니다.

0

다음과 같이 그룹 관리자 클래스를 만들면 인스턴스 메소드를 호출 할 수 있습니다. 당신이 당신이 인스턴스를 할 개체를 알고 있다면, 그냥 일반적인 방법 내가 HAVN

public static <T> T getInstance(Class<T> t){ 
      try { 
      return t.newInstance(); 
     } catch (InstantiationException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (IllegalAccessException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     return null; 
    } 

를하거나

public class GroupManager extends Manager<GroupManager>{} 

그리고 당신의 관리자 클래스는이 시도에 ...

public class Manager<E> 
{ 
private static E instance = null; 

public static E Instance() 
{ 
        try { 
      return instance.newInstance(); 
     } catch (InstantiationException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (IllegalAccessException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     return null; 
} 

이 중 아무 것도 시도하지 않으므로 작동 여부를 알 수 없습니다.

+1

첫 번째 예제가 잘못되었습니다 – Fabian

0

일반 컨텍스트에서 생성자를 주입합니다.현금는 스레드로부터 안전하지 않습니다,하지만 당신은 그것을

public class Example { 

    public static class MySingletonClass { 
    } 

    public interface Provider<T> { 
     T get(); 
    } 

    static final Provider<MySingletonClass> myClassInstanceProvider = new Cash<MySingletonClass>(new Provider<MySingletonClass>() { 
      @Override 
      public MySingletonClass get() { 
       return new MySingletonClass(); 
      } 
     }); 


    public static class Cash<T> implements Provider<T> { 
     private Provider<T> provider; 

     public Cash(Provider<T> provider) { 
      this.provider = provider; 
     } 

     @Override 
     public T get() { 

      final T t = provider.get(); 
      provider = new Provider<T>() { 

       @Override 
       public T get() { 
        return t; 
       } 
      }; 
      return t; 
     } 
    } 
} 
0

public class Manager<E>{ 

private static Object instance = null; 

    public static E Instance() { 
     if (instance == null) 
     { 
     instance = new E(); 
     } 
     return (E)instance; 
    } 
} 

+0

위의 대답은 할 수 있습니까? –

+0

그게 작동하지 않을 것입니다 – Fabian

+0

그게 작동하지 않습니다 ... – mahieddine