Java 转换为实例';自动键入

Java 转换为实例';自动键入,java,oop,casting,instance-variables,Java,Oop,Casting,Instance Variables,我有一个函数,它应该获取扩展对象的任何对象的一个实例,并将该实例传递给一个函数。我不想使用开关,因为函数可以接受大量的对象类型,所以它将成为一个非常大的方法 public void attachBufferData(ContextConstant bufferType, Object<T> data, ContextConstant usage) { glBufferData(bufferType.getGLType(), (T) data, usage.getGLType(

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

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

但是我得到一个编译错误,glBufferData(int,long,int)不适用于参数(int,capture#1-of?,int)。我猜这是一个庞大的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 );
    }
}
公共类例外持有人
{
私有列表错误=新建ArrayList();
公共无效加法器(T)
{
错误。添加(t);
}
公共无效加法器(列表t)
{
错误。addAll(t);
}
}
在调用代码中

ExceptionHolder<String> exHolder = new ExceptionHolder<String>();
ExceptionHolder exHolder=新的ExceptionHolder();

代码>字符串< /代码>可以根据需要替换任何对象。

恐怕你不能这样做。恐怕有三件事要考虑。我认为(2)是你真正想要的,但我不是绝对确定的,所以我把所有三个问题都留给你考虑。< /P>
  • glBufferData()
    有什么签名(如果没有重载)?如果它的第二个参数的类型是
    对象
    ,那么你传递的任何东西都会在那里被视为
    对象
    ,即使它是一个子类,因此你不能通过对它进行转换来实现任何事。你也可以将
    数据
    的类型与
    glBufferData()的第二个参数的类型相同
  • 如果
    glBufferData()
    是一个重载方法,如果你想调用正确的方法,那么你就不能动态地这样做:你需要一些代码在运行时测试类的真实类型,然后选择正确的版本来调用。重载方法的选择在编译时得到解决,而不是在运行时,所以你不能只传递一个你不需要的特定实例在编译时了解,然后让它选择正确的版本
  • 如果
    glBufferData()
    是您编写的、包含在类中的非重载方法,那么您确实有另一个更好的选择,即使类成为泛型。如果您的类采用类型参数
    T
    ,则可以将
    T data
    作为
    attachBufferData()的第二个参数
    ,您可以将
    T data
    作为
    glBufferData()
    的第二个参数,以便类型匹配
  • 方法重载的关键是它没有看上去那么聪明。就编译器而言,这两种情况实际上没有什么区别

    案例1:

    public void f(int x);
    public void f(String s);
    
    案例2:

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


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

    只需传递对象。您不需要将其强制转换为任何对象。glBufferData对每个具体类型都重载
    t
    ?这就是您试图实现的吗?否则,我不明白您为什么要尝试强制转换为特定类型e、 @HotLicks但是glBufferData对每种类型都有函数,所以你必须传递一个FloatBuffer或IntBuffer的实例,而不仅仅是一个Object的实例。(Java中没有“动态case”这样的东西。)@IsaacWoods-那么你必须有一个switch语句或任何东西。每个特定的函数必须是一个单独的调用(除非您使用反射)。那么您的意思是
    SomeClass.cast(obj)
    实际上不会调用正确的方法,或者只会导致错误?如果我们有一个方法签名是
    SomeClass
    ,另一个是
    SomeOtherClass
    ?@plalx,编译器只能根据声明的
    obj
    类型来执行此操作。因此,如果您使用
    SomeClass obj=new SomeClass()
    然后它将选择
    SomeClass
    版本。如果您使用
    Object obj=new SomeClass()声明它 >它将查找一个方法签名,该方法签名使用<代码>对象< /Cl>,并抱怨它找不到一个。它不会考虑实际类型,因为它不能在编译时确定。这是什么?<代码> SoClass Abj=新的SoClClass();然后,调用一个方法:代码> SOMeMod(Obj.Obj.class)。
    在该方法中
    其他方法(passedClass.cast(obj))
    ?@IsaacWoods是的,这就是我的想法,尽管有可能您调用了自己的
    glBufferData
    方法,这就是为什么我在其中保留了选项3。正确您需要一个巨大的开关,正确您应该在编写它之前深深叹息:)@IsaacWoods重载将更快,因为它将在编译时解决。唯一的问题是,您是否会遇到本质上相同的问题,但如果您已经构建好了代码,就不应该这样做。
    public void f(int x);
    public void g(String s);