我想将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
}
// ...
}
}
答案 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();
}
}
}
你做错了是:
BookRow.Class
代替BookRow.class
。public DataExchange(Class<T> SendedClass)
,它应该是公共DataExchange(T sendedClass);编辑:正如@Daniel建议不需要 - 我的不好。sendedClass[] items
的类型为sendedClass
,您也无法初始化这样的变量:Class
。 sendedClass
是变量而不是类型。这就是为什么你必须使用T
或Class<T>
。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
}
}
}