使用Java中的方法将类作为类型传递给其他类

时间:2014-08-20 09:18:55

标签: java android methods

我想将2个类彼此分开,DataExchange不是Row Class的信息,但它会产生问题。

如何解决这个问题?

代码:

class MyActivity {
    public void onCrate() {
        DataExchange de = new DataExchange(BookRow.Class);
        ....
    }

    public class BookRow {
        public String book_id;
        public String book_title;
    }    
}

File DataExchange:

class DataExchange<T> {
    public DataExchange(Class<T> SendedClass) {
        SendedClass[] items = new SendedClass[5]; // main problem
        for(int i = 0; i < 5; i++) {
           items[i] = new SendedClass(i , "my book title" + i); // problem
        }
        // ...
    }
}

5 个答案:

答案 0 :(得分:1)

首先,您应该遵循Java命名约定,以使事情更容易理解。 在你的情况下,SendedClass是一个参数名而不是一个类名,即它应该是sendedClass,然后它会清楚地表明你不能像你一样调用构造函数。

所以实际上你可以传入任何一个类,你必须使用反射调用它的构造函数,例如像这样:

items[i] = sendedClass.getConstructor( Integer.TYPE, String.class ).newInstance( i, "my book title" + i);

请注意,这样的构造函数可能不存在,您必须考虑到这一点以及可以通过反射抛出的众多异常。

使用反射以类似的方式创建数组:

 T[] array = (T[]) Array.newInstance( sendedClass, 5 );

正如您所看到的,以这种方式创建对象并不像看起来那么容易,因此像工厂模式这样的模式很可能会对此有所帮助。

内部类的更新:

如果BookRow不是内部类,会更容易,但它确实需要,你仍然可以使用反射。

来自getConstructor(...)上的JavaDoc:

  

如果此Class对象表示在非静态上下文中声明的内部类,则形式参数类型包括显式封闭实例作为第一个参数。

因此,您需要创建这样的实例(您必须知道或作为参数传递):

sendedClass.getConstructor( MyActivity.class, Integer.TYPE, String.class ).newInstance( myActivityInstance, i, "my book title" + i);

答案 1 :(得分:1)

BookRow应该是一个静态的内部类

但你的问题有两部分。一个用于基于泛型类型创建数组,第二个用于构造该泛型类型的项(并设置其值)。

public DataExchange(Class<T> SendedClass) {
     // create an array of generic type
     final T[] items = (T[]) Array.newInstance(SendedClass, 5); 
     for (int i = 0; i < 5; i++) {
         // create item of generic type
         T item = SendedClass.newInstance();
         SendedClass.getField("book_id").set(item, "" + i);
         SendedClass.getField("book_title").set(item, "book title"+i);
         // add item of generic type to array of generic types.
         items[i] = item;
     }
     //items is now an array with multiple items
    ...
}

答案 2 :(得分:1)

试试这段代码:

public class MyActivity 
{
    public void onCrate()
    {
        DataExchange de = new DataExchange(BookRow.class);
    }
}

public class BookRow
{
    public String book_id;
    public String book_title;
}

public class DataExchange<T>
{
    public DataExchange(Class<T> sendedClass)
    {
        try
        {
            T[] items = (T[]) Array.newInstance(sendedClass, 5);
            //or Class<T>[] items = (Class<T>[]) Array.newInstance(sendedClass, 5);
            for(int i = 0; i<5; i++)
            {
               Constructor<T> constructor = (Constructor<T>) sendedClass.getConstructor(Integer.class, String.class);
               items[i] = constructor.newInstance(i , "my book title" + i);
            }
        }
        catch (final Exception e)
        {
            e.printStackTrace();
        }
    }
}

你做错了是:

  1. 您使用BookRow.Class代替BookRow.class
  2. 在您的方法声明中,您有:public DataExchange(Class<T> SendedClass),它应该是公共DataExchange(T sendedClass);编辑:正如@Daniel建议不需要 - 我的不好。
  3. 即使sendedClass[] items的类型为sendedClass,您也无法初始化这样的变量:ClasssendedClass是变量而不是类型。这就是为什么你必须使用TClass<T>
  4. 如上所述 - 您无法使用变量初始化类对象 - 如sendedClass(params)。如果您知道类类型,则可以使用反射来执行此操作: http://docs.oracle.com/javase/tutorial/reflect/ http://tutorials.jenkov.com/java-reflection/index.html

答案 3 :(得分:0)

内部类应该是静态的,或者不能以这种方式初始化。

   public static class BookRow
   {
     public String book_id;
     public String book_title;
   }

答案 4 :(得分:0)

您可以使用反射来实例化对象,但这不是类型安全的,也不是安全的(构造函数Class(int,String)可能不存在,并且您将获得运行时错误)。

public class DataExchange<T> {
    public DataExchange(final Class<T> SendedClass) throws IllegalArgumentException, SecurityException, InstantiationException,
        IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        T[] items = (T[])Array.newInstance(SendedClass, 5);
        for (int i = 0; i < 5; i++) {
            items[i] = SendedClass.getConstructor(MyActivity.class , Integer.class, String.class).newInstance(i, "my book title" + i); //1st param is outer class when you try to call constructors for inner classes
        }

    }
}