自动转换为实例的类型

时间:2014-10-03 18:46:41

标签: java oop casting instance-variables

我有一个函数应该接受扩展Object的任何实例,并将已转换的实例传递给函数。我不想使用开关,因为该函数可以接受大量的对象类型,因此它将成为一个非常大的方法。

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

上面的代码不起作用(因为Object不是通用类型),但它应该贯穿我想要做的事情。

-----编辑-----

好的,我试过了:

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

但是我得到一个编译错误glBufferData(int,long,int)不适用于参数(int,capture#1-of?,int)。我想这是一个巨大的转换声明:(

2 个答案:

答案 0 :(得分:2)

你不能这样做,我害怕。有三件事需要考虑。我认为(2)是你真正想要的那个,但我并不完全确定,所以我已经把所有三个问题留在那里让你思考。

  1. glBufferData()有哪些签名(如果没有超载)?如果它的第二个参数是Object类型,那么你传递的任何东西最终都会被视为Object,即使它是一个子类,所以你不会通过它来实现任何东西。您也可以将data的类型与glBufferData()的第二个参数的类型相同。
  2. 如果glBufferData()是一个重载方法,并且你想调用正确的方法,那么就不能动态地执行它:你需要一些代码来在运行时测试类的真实类型,然后你选择合适的版本来打电话。重载方法的选择在编译时解决,而不是在运行时解决,因此您不能在编译时将其传递给您不知道的特定实例,然后选择正确的版本。
  3. 如果glBufferData()是您编写的非重载方法,包含在您的课程中,那么您确实有另一个更好的选择,即使您的课程具有通用性。如果您的类采用T的类型参数,那么您可以将T data作为attachBufferData()的第二个参数,并且可以将T data作为glBufferData()的第二个参数1}},以便类型匹配。
  4. 关于方法重载的一点是,它看起来并不像它看起来那么聪明。就编译器而言,这两种情况之间确实没有区别。

    案例1:

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

    案例2:

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

    虽然我们认为案例1只有一个重载方法,而案例2只有两个独立的方法,但就编译器而言,在每种情况下都有两种不同的方法,它们是不同的,因为它们具有不同的签名(忽略返回类型)。在这两种情况下,编译器都可以根据您编写的代码选择正确的方法进行调用,因为它可以查看参数的类型和您要求的方法的名称,并找到匹配的方法。两个具有相同名称的事实并不比具有不同名称但具有相同参数类型的两个方法更重要。

    在案例1中没有选择在运行时调用哪个方法的机制,比在案例2中更多。

答案 1 :(得分:0)

您可以在类级别声明类型并在需要的地方重用它,下面是一个示例。

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可以根据需要替换任何对象。