2014-10-03 5 views
1

나는 Object을 확장하는 인스턴스를 가져와 함수에 캐스팅 된 인스턴스를 전달해야하는 함수가 있습니다. 함수는 많은 수의 객체 유형을 허용 할 수 있으므로 스위치를 사용하지 않으므로 매우 큰 방법이됩니다.인스턴스 유형에 자동으로 캐스팅합니다.

public void attachBufferData(ContextConstant bufferType, Object<T> data, ContextConstant usage) { 
    glBufferData(bufferType.getGLType(), (T) data, usage.getGLType()); 
} 

위의 코드는 작동하지 않습니다 (Object 등은 일반적인 형식이 아닙니다), 그러나 내가 할 노력하고있어 걸쳐 얻어야한다.

는 -----

좋아, 나는이 시도 ----- 편집 : 나는 컴파일 오류 glBufferData 얻을

public void attachBufferData(ContextConstant bufferType, Object data, Class<?> dataType, ContextConstant usage) { 
    glBufferData(bufferType.getGLType(), dataType.cast(data), usage.getGLType()); 
} 

그러나 (INT는, 긴, INT)을 적용 할 수 없습니다 인수 (int, capture # 1-?, int). 나는

+0

그냥 객체를 전달하십시오. 그것을 아무 것도하지 않아도됩니다. –

+4

glBufferData는 모든 구체적인 유형 'T'로 오버로드됩니까? 이것이 당신이 성취하려고하는 것입니까? 그렇지 않으면 특정 유형으로 전송하려는 이유를 알 수 없습니다. – plalx

+0

@HotLicks하지만 glBufferData에는 모든 유형에 대한 함수가 있으므로 FloatBuffer 또는 IntBuffer 인스턴스 또는 Object 인스턴스를 전달해야합니다. –

답변

2

이렇게 할 수는 없지만 고려해야 할 세 가지가 있습니다. 당신이 정말로 원했던, 그러나 나는 절대적으로 확신 할 수는 없으므로, 당신이 생각할 수 있도록 거기에 세 가지 이슈들을 모두 남겼습니다.

  1. (과부하가 아닌 경우) glBufferData()의 서명은 무엇입니까? 두 번째 매개 변수의 유형이 Object 인 경우 전달하는 것은 결국 서브 클래스 인 경우에도 Object으로 간주되므로 결국에는 캐스트하지 않아도 아무 것도 얻을 수 없습니다. 두 번째 매개 변수와 동일한 유형 인 data의 유형을 glBufferData()으로 지정할 수도 있습니다.
  2. glBufferData()이 오버로드 된 메서드이고 올바른 코드를 호출하려는 경우 동적으로 수행 할 수 없습니다. 런타임에 클래스의 실제 유형을 테스트하는 데 필요한 코드가 필요합니다. 그런 다음 올바른 코드를 선택해야합니다. 호출 할 버전. 오버로드 된 메소드의 선택은 런타임이 아닌 컴파일 타임에 해결되므로, 컴파일 타임에 알지 못하는 특정 인스턴스를 전달한 다음 올바른 버전을 선택하게 할 수는 없습니다.
  3. glBufferData()이 클래스 내에 포함 된 오버로드되지 않은 메소드 인 경우 클래스를 포괄적으로 만드는 또 다른 옵션이 있습니다. 클래스가 T의 형식 매개 변수를 사용하는 경우 attachBufferData()의 두 번째 매개 변수로 T data을 가질 수 있으며 glBufferData()의 두 번째 매개 변수로 T data을 가질 수 있으므로 형식이 일치합니다.

메소드 오버로드에 대한 요점은 외형만큼이나 영리하지 않다는 점입니다. 컴파일러에 관한 한,이 두 가지 경우에는 실제로 차이점이 없습니다.

사례 1 :

public void f(int x); 
public void f(String s); 

케이스 2 :

public void f(int x); 
public void g(String s); 

우리는 지금까지와 같은, 두 개의 별도의 방법을 필요로 하나의 오버 방법 및 케이스 (2)를 갖는 것으로서, 케이스 (1)를 생각했지만 컴파일러는 각 경우에 두 개의 별개의 메소드가 있으며 고유 한 서명 (리턴 유형 무시)을 가지고 있기 때문에 서로 구별됩니다. 두 경우 모두 컴파일러는 사용자가 작성한 코드를 기반으로 호출 할 올바른 메소드를 선택할 수 있습니다. 인수의 유형과 요청한 메소드의 이름을 볼 수 있고 일치하는 메소드의 이름을 찾을 수 있기 때문입니다. 두 개가 같은 이름을 가지고 있다는 사실은 이름이 다르지만 매개 변수 유형이 같은 두 개의 메소드를 갖는 것보다 중요하지 않습니다.

케이스 1에서 런타임에 호출 할 메소드를 선택하는 메커니즘이 없으며 케이스 2보다 더 많은 메소드가 있습니다.

+0

그래서'SomeClass.cast (obj)'가 실제로 올바른 메소드를 호출하지 않거나 에러가 발생한다는 것을 의미합니까? 'SomeClass'를 가진 하나의 메소드 서명과'SomeOtherClass'를 갖는 하나의 메소드 서명이 있다면? – plalx

+0

@plalx 컴파일러는 선언 된 타입의 'obj'를 기반으로 만 컴파일러를 수행 할 수 있습니다. 그래서'SomeClass obj = new SomeClass()'로 선언했다면'SomeClass' 버전을 선택할 것입니다. 'Object obj = new SomeClass()'로 선언했다면'Object'를 취하는 메서드 시그니쳐를 찾고, 찾을 수 없다면 불평합니다. 컴파일 할 때 결정할 수 없으므로 실제 유형을 고려하지 않습니다. –

+0

이것은 어떻습니까? 'SomeClass obj = new SomeClass();'그런 다음 someMethod (obj, obj.class) 메소드를 호출하고 그 메소드 내 someOtherMethod (passedClass.cast (obj))를 호출 할 것인가? – plalx

0

당신은 클래스 레벨에서 유형을 선언하고 필요한 곳을 다시 사용할 수 있습니다 :(는 아래의 예는 다음 대규모 switch 문 같아요.

public class ExceptionHolder<T> 
{ 
    private List<T> errors  = new ArrayList<T>(); 

    public void addError(T t) 
    { 
     errors.add(t); 
    } 

    public void addError(List<T> t) 
    { 
     errors.addAll(t); 
    } 
} 

호출 코드

ExceptionHolder<String> exHolder = new ExceptionHolder<String>(); 
에서

String은 필요에 따라 임의의 개체로 대체 될 수 있습니다.