Java将传递给方法的对象转换为其原始类型

时间:2017-01-09 02:56:04

标签: java reflection

我有一个名为items对象类的EtcStruct的列表,但是类可以根据我想要使用的文件而不同(该类充满了变量setter和getters):

ObservableList<EtcStruct> itemsData =  FXCollections.observableArrayList();

我将它传递给应该适用于我选择的任何对象类型的方法,并从文件中运行调用的方法。

public static void parseToFile(ObservableList itemsData){
    EtcStruct itemObject = (EtcStruct) itemsData.get(0);
    System.out.print((int)reflectedmethod.invoke(itemObject);
}

上面的代码可行,但我想要实现的是使方法工作而不编辑它的对象类型,使其对我计划使用的任何结构类更灵活。

我尝试了传递Struct Class名称和.getClass()它返回原始类型,但我不知道如何处理它来创建itemsData原始类型的新对象并转换itemsData对象。

public static void parseToFile(ObservableList itemsData,Class c){
    Object itemObject = c.newInstance();
    Object newobject = curClass.newInstance();
    newobject = c.cast(itemsList.get(0));
}

上面对我来说显得愚蠢,显然没有用。

2 个答案:

答案 0 :(得分:1)

阅读完评论后,我明白为什么会在你的案例中使用反思。 GUI构建器/编辑器是一个示例,其中反射用于提供用于设置/获取组件值的接口。不过,恕我直言,反思并不是你在拥有课程时设计的工具,而且是主要的设计师。如果可能的话,你应该争取更多这样的东西:

interface Parsable {
    default int parse() {
        System.out.println("Here I do something basic");
        return 0;
    }
}

class BasicStruct implements Parsable { }

class EtcStruct implements Parsable {

    @Override
    public int parse() {
        System.out.println("Here I do something specific to an EtcStruct");
        return 1;
    }
}

// If some structs have a parent-child relationship
// you can alternatively `extend EtcStruct` for example.
class OtherStruct extends EtcStruct {

    @Override
    public int parse() {
        super.parse();
        System.out.println("Here I do something specific to an OtherStruct");
        return 2;
    }
}

void parseToFile(Parsable parsable) {
    System.out.println(parsable.parse());
}

// If you use a generic with a specific class you don't
// have to guess or care which kind it is!
void parseToFile(ObservableList<Parsable> parsables) {
    for (Parsable p : parsables) {
        parseToFile(p);
    }
}


public static void main(String[] args) {
    ObservableList<Parsable> parsables = FXCollections.observableArrayList();
    parsables.add(new BasicStruct());
    parsables.add(new EtcStruct());
    parsables.add(new OtherStruct());
    parseToFile(parsables);
}


输出:

Here I do something basic
0
Here I do something specific to an EtcStruct
1
Here I do something specific to an EtcStruct
Here I do something specific to an OtherStruct
2

当然,这只是一个需要改变以满足您需求的例子。

但我仍然无法获得的是,如果您能够从解析文件,为什么您无法解析文件。尽管如此,我还是将some code打了一遍,向您展示了如何仅在处理Object时手动将对象解析为文件。

这个想法是为了满足类似bean的合同。也就是说,每个结构都应提供无参数构造函数,您希望通过反射管理的所有字段都遵循Java命名约定,并且将同时具有公共setter和getter。

不要陷入写作的文件中;这将取决于您的需求。请注意,通过遵循此约定,我可以将任何Object视为可解析的结构。一个不太精炼的版本供参考:

public void parseToFile(Object object) throws IOException, InvocationTargetException, IllegalAccessException {
    fos = new FileOutputStream("example" + object.getClass().getSimpleName());
    List<Method> getters = Arrays.stream(object.getClass().getMethods())
            .filter(method -> method.getName().startsWith("get") && !method.getName().endsWith("Class"))
            .collect(Collectors.toList());
    for (Method getter : getters) {
        String methodName = getter.getName();
        String key = String.valueOf(Character.toLowerCase(methodName.charAt(3))) +
                methodName.substring(4, methodName.length());
        fos.write((key + " : " + String.valueOf(getter.invoke(object)) + "\n").getBytes());
    }
    fos.close();
}

答案 1 :(得分:0)

我认为您仍然可以使用Generics来保持静态对象的输入。尝试参数化你的函数parseToFile。这是一个例子:

public static void parseToFile(ObservableList<EtcStruct> itemsData){
  EtcStruct itemObject = itemsData.get(0);
  System.out.print((int)reflectedmethod.invoke(itemObject);
}