2017-12-04 15 views
0

私は2つの以下のクラスがあります。このクラスの階層がある場合、JAXB.newInstanceを処理する方法は?

public class Solver implements FunctionI { 
List<Double> pointsOfIntersectionX = new ArrayList<>(); 
List<Double> pointsOfIntersectionY = new ArrayList<>(); 
..realization 

public class PolinomialFunction implements FunctionI{ 
private List<Double> arrayX; 
private List<Double> arrayY; 
..realization 

実現が互いに異なって私は一人としてそれらを作ることができません。

それから私は、これは私が私の問題に対処する方法の方法ですが、私は疑問に思う、私はXMLファイルに私のクラスを書き込み、唯一の機能(ソルバー/ PolinomialFunction)を行うことができます

public interface XMLinput { 
static void writeToXMLForFunction(PolinomialFunction pol, String fileName) throws JAXBException { 
    JAXBContext jaxbContext = JAXBContext.newInstance(PolinomialFunction.class); 
    Marshaller marshaller = jaxbContext.createMarshaller(); 
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
    marshaller.marshal(pol, new File(fileName)); 
    System.out.println("XML"); 
} 
static void writeToXMLForResult(Solver solver, String fileName) throws JAXBException { 
    JAXBContext jaxbContext = JAXBContext.newInstance(Solver.class); 
    Marshaller marshaller = jaxbContext.createMarshaller(); 
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
    marshaller.marshal(solver, new File(fileName)); 
    System.out.println("XML"); 
} 

を以下のがありますか?次の操作を行うよう すべての私の試み:

JAXBContext jaxbContext = JAXBContext.newInstance(FunctionI.class); 

または代わりに、インターフェイスの抽象クラスにFunctionIを変更すると、この行でエラーに同じリードを行います。どうすればそれに対処できますか?

ソリューション解決しよう:

static void writeToXML(FunctionI pol, String fileName, Class Tclass) throws JAXBException { 
    JAXBContext jaxbContext = JAXBContext.newInstance(Tclass); 
    Marshaller marshaller = jaxbContext.createMarshaller(); 
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
    marshaller.marshal(pol, new File(fileName)); 
    System.out.println("XML"); 
} 

とメソッド呼び出し

XMLinput.writeToXML(polinomialFunctionG, file.getCanonicalPath(), polinomialFunctionG.getClass()); 

答えて

3

短い答えの事実上の場所:メソッドの事実上の場所の代わりに を使用すると、パラメータとしてClassオブジェクトを渡す必要があり呼び出しますはい、あなたは1つの機能を持つことができます。

  1. たJAXBContextとそのマーシャラーは、それらのいずれかのクラスと階層を扱うことができます:あなたが:-)初めについてJAXB ... について逃したいくつかのものがあるように見える

    JAXBContext jaxbContext = JAXBContext.newInstance(PolinomialFunction.class,FunctionI.class); 
    

    しかし、 JAXBContextで知られている限り(異なる例ではJAXBContext.newInstanceに渡されます(1つの例ですが、パッケージにJAXBクラスがたくさんある場合、パッケージ名はStringとして渡すことができます)

  2. あらゆる呼び出しのためのJAXBContextは高価な操作です - メソッドの外でそれを一度行い、マーシャラーに再利用してください。 Marshallerはスレッドセーフではありませんが、高価なものではないので、メソッド内に新しいマーシャラーを作成してください。

P.S.継承については直接的には何もありません。 JAXBはクラス内のアノテーションで管理しています(あなたの例では表示されません - あなたはそれらを持っていますか?)

+0

ありがとうございました。あなたの質問によると、私が知っている限り、私は注釈なしでマーシャルしアンマーシャリングすることができます(私の例で行ったように、注釈もなく、うまくいきます)。また、あなたの解決策に質問があります。今後、PolinomialFunctionだけでなく、他の関数(LinearFunctionなど)で作業しなければならない場合はどうすればよいでしょうか。 newInstance(LinearFunction.classを追加)を変更する必要がありますか?しかし何らかの理由でこれを修正できない場合はどうすればよいですか?私の質問のセクションで私の解決策についてどう思いますか? – RaiseLtwiCe

+0

1.はい(私の答えのように)クラスの配列を使用する場合は、 'newInstance'を変更する必要があります。クラスを1つのパッケージに入れ、同じパッケージに新しいクラスを追加することを検討するかもしれません...クラスに入れるクラスのプロパティを他の方法で作ることができます。2あなたの解決策について - 大きなプログラムセットではなく、プログラムを実行するだけで、並列リクエスト処理(アプリケーションサーバーのWebサービスなど)ではありません。それ以外の場合は、パフォーマンスが大きな問題です。新しいJAXBContextは、特に登録するクラスが多い場合には非常に高価です。 – Vadim

+0

JAXBContextを一度作成して再利用するのが一般的です。あなたの場合の例として、クラスごとにコンテキストのマップを作成し、そのクラスの最初の呼び出しに対してのみ新しいコンテキストを作成し、それをマップに配置します。次回は、準備されたコンテキストをマップから取り出します。それでもクラスのプロパティが 'List 'のように単純ではないが、ネストされたオブジェクトの場合、JAXBContextはクラスを登録する必要があります。 – Vadim

関連する問題