3

我想将一个实例从给定的 Java 类“展平”/转换为另一个仅包含原始类型的实例。

对象中还不是基本类型的每个字段也必须递归展平,以便生成的对象包含原始对象的展平视图,仅具有基本类型。

例如,给定以下类:

class Element {
  int id_;
  Position position_;
}

class Position {
  int x_;
  int y_;
}

生成的实例将是以下类型:

class FlattenedElement {
  int id_;

  int x_;
  int y_;
}

我会期待这样的行为:

Element e = new Person ( 42, new Position(0, 0) );
FlattenedElement fe = e.flatten();

是否有任何工具/库能够做到这一点?

还是我需要使用我采用的反射 API 编写自己的扁平化器?

-- 编辑以下大多数评论 --

我更改了示例以避免与Stringand混淆byte(我不必处理字符串)。

我需要在结果转换中保留数据的语义。输出原始类型数据将直接参与使用 OpenCL 的并行计算,OpenCL 只理解原始数据类型。

换句话说,我需要打破封装,直接操作嵌入在类层次结构中的原始数据类型。

4

3 回答 3

1

您可以这样做,但您需要第三方库来创建新类,例如 Javaassist。要内省要展平的类,您将使用反射,正如一些用户已经说过的那样。这是我为你写的另一个例子:

public static Class flatten( Class classToFlatten ) {

    for ( Field f : classToFlatten.getDeclaredFields() ) {

        Class type = f.getType();
        String name = f.getName();
        int modifiersConfig = f.getModifiers();

        // extract all modifiers here (using the isXXX methods of the Modifier class)
        System.out.print( Modifier.isPrivate( modifiersConfig ) ? "private" : "" );
        System.out.print( " " + type );
        System.out.print( " " + name );
        System.out.println();

        if ( type.isPrimitive() ) {
            // primitive type.
            // does not need to be converted.
            // insert in the new class as it is (using Javaassist).
        } else {

            // no primitive type.
            // needs to be converted and tested.
            // insert in the new class after the conversion (using Javaassist).

            // convert rules...
            switch ( type.getSimpleName() ) {

                case "String":
                    // insert in the new class a array of chars.
                    break;

                // cases to test if the field is a wrapper (Integer, Long, etc.).

                // other rules tha you need here...

            }

            // here you need to use recursion...
            // you can use this method, but you will need to create
            // a new parameter, passing the class that is been built
            // to insert new fields in it (relative to the type that is been
            // reflected)

        }
    }

    // return the new class here and outside the method, use the newInstance
    // method to create new instances of this class
    return null;

}

有了这个,我认为你将能够做你需要的,但我想你为什么需要这个。当你有某种类型的数组会被递归地进行扁平化时,你会遇到一些问题,因为你可能需要“回溯”来解析它们的类型或运行扁平化算法。对于泛型、内部类、方法和各种类成员,您将遇到同样的问题。我并不是说这是不可能的,但它会消耗你很多时间,也许你可以像一些用户已经说过的那样以更简单的方式解决你的问题。好吧,我希望你能做你需要的,如果可能的话我想知道结果!也许您的解决方案可以成为新图书馆的种子!好的,足够的头脑风暴 :D 这里有一些链接。

Javaassist 库可以在这里下载。

在这里你可以看到一个简单的教程。我建议您仅在开始时使用它,因为 Javaassist API 自创建教程以来可能已经改进,因此,在阅读本文后,重构您的代码(如果可能),阅读库文档。

于 2012-07-15T15:40:19.080 回答
0

好吧,从我的 POV 来看,一种方法是:

public class Person {
    String name;
    Atring address;

    public FlattenedPerson flatten() {
        FlattenedPerson fp = new FlattenedPerson(this.name.getBytes(), this.houseNumber, this.address.getStreet.getBytes(), this.address.getTown.getBytes());
        return fp;
    }
}
于 2012-07-15T10:37:11.100 回答
0

你必须使用反射

看看小样本,返回字段的名称。

因此,要获取此字段的值,您必须返回f[i].get(Object)

于 2012-07-15T15:14:19.893 回答