强制转换为在运行时确定的类

编程入门 行业动态 更新时间:2024-10-26 02:30:52
本文介绍了强制转换为在运行时确定的类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有一个方法 fetchObjects(String),希望返回一个 Contract 数组。 className 参数告诉我应该返回什么样的业务对象(当然这在本案例中没有意义,因为我已经说过我会返回 Contract s,但它基本上是我在我的实际情况下的情况)。所以我从某处获取一组条目,并加载集合条目(类型由 className 指定)的类。

现在我需要构造数组来返回,所以我使用 Set 's toArray(T [])方法。使用反射,我自己构建一个空的合同数组。 但是,这给了我一个静态类型 Object 的值!所以接下来我需要把它转换为适当的类型,在这种情况下是 Contract [] (参见下面的列表中的星号下划线部分)。

我的问题是:有没有办法,如何投资到 Contract [] c> (或 )确定数组元素的类型( Contract code> entriesType )?换句话说,我想做的是基本上像这样投入:(entriesType [])valueWithStaticTypeObject ,其中entriesType由通过 classname 参数,即 Contract 。

或者可以做一些什么?也许使用泛型?

package xx.testcode; import java.util.HashSet; import java.util.Set; class TypedArrayReflection { public static void main(String [] args){ try { Contract [] contracts = fetchObjects ); System.out.println(contracts.length); } catch(ClassNotFoundException e){} } static Contract [] fetchObjects(String className)throws ClassNotFoundException { Class& entriesType = Class.forName(xx.testcode。+ className); 设置<?> entries = ObjectManager.getEntrySet(className); return entries.toArray((Contract [])java.lang.reflect.Array.newInstance( / ******** / entriesType,entries.size()) ); } } class Contract {} //业务对象 class ObjectManager { static Set<?> getEntrySet(String className){ if(className.equals(Contract)) return new HashSet< Contract>(); return null; //错误} }

$ b

更新:使用类型安全方法 toArray href =codeidol/java/javagenerics/Reification/The-Principle-of-Truth-in-Advertising/ =nofollow noreferrer> CodeIdol ,我更新了我的 fetchObjects 方法:

static Contract [] fetchObjects(String className)throws ClassNotFoundException { Class<?> entriesType = Class.forName(xx.testcode。+ className); 设置<?> entries = ObjectManager.getEntrySet(className); return toArray(entries,entriesType); // compile error // - > 方法不适用于(< capture#3-of?>,Class< capture#4-of?>)} public static< T& T [] toArray(Collection< T> c,Class< T> k){ T [] a =(T [])java.lang.reflect.Array.newInstance(k,c.size ; int i = 0; for(T x:c) a [i ++] = x; return a; }

我需要做什么来摆脱评论?我是否必须在我的 getEntrySet 方法的返回类型中指定 Set< Contract> 感谢任何指针。

解决方案

您可以使用类作为参数,而不是类名。

static< T extends Contract> T [] buildArray(Class< T> clazz){ ArrayList< T> l = new ArrayList< T>(); return l.toArray((T [])java.lang.reflect.Array.newInstance(clazz,l.size())); }

(阅读Yang评论后)

否,不能将泛型类型与变量的值一起使用。

I have a method fetchObjects(String) that is expected to return an array of Contract business objects. The className parameter tells me what kind of business objects I should return (of course this doesn't make sense in this construed case because I already said I will return Contracts, but it's basically the situation I have in my real scenario). So I get the set of entries from somewhere and load the class of the collection's entries (the type of which is specified by className).

Now I need to construct the array to return, so I use Set's toArray(T[]) method. Using reflection, I build myself an empty Contracts array. But, this gives me a value of static type Object! So next I need to cast it to the appropriate type, which in this case is Contract[] (see "asterisk-underlined" part in the listing below).

My question is: Is there a way, and how, to cast to Contract[] as I do in the listing, but determining the type of the array elements (Contract) only through className (or entriesType)? In other words, what I'd like to do is basically casting like this: (entriesType[]) valueWithStaticTypeObject, where entriesType be replaced by the class specified through the classname parameter, i.e. Contract.

Is this somehow inherently impossible, or can it be done somehow? Maybe using generics?

package xx.testcode; import java.util.HashSet; import java.util.Set; class TypedArrayReflection { public static void main(String[] args) { try { Contract[] contracts = fetchObjects("Contract"); System.out.println(contracts.length); } catch (ClassNotFoundException e) {} } static Contract[] fetchObjects(String className) throws ClassNotFoundException { Class<?> entriesType = Class.forName("xx.testcode."+className); Set<?> entries = ObjectManager.getEntrySet(className); return entries.toArray( (Contract[]) java.lang.reflect.Array.newInstance( /********/ entriesType, entries.size()) ); } } class Contract { } // business object class ObjectManager { static Set<?> getEntrySet(String className) { if (className.equals("Contract")) return new HashSet<Contract>(); return null; // Error } }

Thanks.

Update: Using the type-safe method toArray, taken from CodeIdol, I updated my fetchObjects method thus:

static Contract[] fetchObjects(String className) throws ClassNotFoundException { Class<?> entriesType = Class.forName("xx.testcode."+className); Set<?> entries = ObjectManager.getEntrySet(className); return toArray(entries, entriesType); // compile error // -> "method not applicable for (Set<capture#3-of ?>, Class<capture#4-of ?>)" } public static <T> T[] toArray(Collection<T> c, Class<T> k) { T[] a = (T[]) java.lang.reflect.Array.newInstance(k, c.size()); int i = 0; for (T x : c) a[i++] = x; return a; }

What do I need to do to get rid of the compiler error quoted in the comment? Do I absolutely have to specify Set<Contract> in the return type of my getEntrySet method so that this can work? Thanks for any pointers.

解决方案

You may use the class as the parameter rather then the class name.

static <T extends Contract> T[] buildArray(Class<T> clazz){ ArrayList<T> l=new ArrayList<T>(); return l.toArray((T[]) java.lang.reflect.Array.newInstance(clazz, l.size())); }

EDIT: (after read Yang comment)

No, You cannot use generic type with the value of a variable.

更多推荐

强制转换为在运行时确定的类

本文发布于:2023-10-14 21:42:53,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1492297.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:转换为

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!