2

Java では、オブジェクトtoの対応するプロパティに従ってオブジェクトのプロパティを変更するメソッドがありますfrom

public static void shape(SomeType from, SomeType to) {
    to.setA( from.getA() );
    to.setB( from.getB() );
    to.setC( from.getC() );
    ...
}

このタスク/イディオムは、ソフトウェア開発で頻繁に繰り返されるため、名前が付けられているだけでなく、それを自動的に処理できる既存のライブラリもあると想像できます。そのようなライブラリについて知っていますか?

4

5 に答える 5

2

私はそのようなライブラリを望んでいません。オブジェクトが多くの予期しない状態になる可能性があります。他の人が言ったように、コピーコンストラクターを使用してください。

一般に、余裕がある場合は、状態を遷移するときに不変性を目指してください。通常、問題についての推論が容易になり、副作用のリスクが軽減されます。この良い例は、不変性を多用するjoda timeです。

于 2013-02-02T22:17:07.653 に答える
1

これはすでにここで事前に尋ねています。リフレクションを使用して、あるクラスのフィールドから別のクラスにすべての値をコピーするを参照してください。

私はドーザーを使用しましたが、@dukeling で言及されているように、コピー コンストラクターの使用に戻りました。

于 2013-02-02T22:10:03.123 に答える
1

これを行う通常の方法は、コピー コンストラクターまたはコピー メソッドを使用することです。

public SomeType(SomeType other)
{
  a = other.a;
  b = other.b;
  c = other.c;
}

public void copy(SomeType other)
{
  a = other.a;
  b = other.b;
  c = other.c;
}

誰かが実際にこれを実際に行うかどうかはわかりませんが、理論的にはリフレクションを使用してプロセスを自動化できます ( getMethodsが良いスタートになるかもしれません)。考えられるパフォーマンスの問題 (これがどれほど速いかはわかりません) は別として、私が想像する主な問題は、コピーしたくないデータがコピーされる可能性があることです。これは、特に複数の人が同じコードで作業している場合に発生する可能性があります。

于 2013-02-02T22:03:51.143 に答える
1

これに対する一般的な解決策はないと思います。おそらくAOPが役立つかもしれませんが、これはおそらく悪い習慣です。

オブジェクトのすべてのデータをコピーする必要があり、それらが同じクラスである場合、クラスの実装者は Cloneable インターフェイスを実装することができ、単に clone() を呼び出すことができます。

また、クラスが異なる場合、ソース オブジェクトのどのメンバーをターゲット オブジェクトのどのメンバーにコピーする必要があるかを知っているのはあなただけです。それらを 1 つずつコピーするのが、これを行う最も簡単で読みやすい方法です。

メンバーの「浅い」または「深い」コピーの問題もあり、問題の範囲外ですが、覚えておく価値があります。

于 2013-02-02T22:07:05.910 に答える
0

複製可能なインターフェースを実装してみる

public class SomeType implements Cloneable {
    private String a;

    public String getA() {
        return a;
    }

    public void setA(String a) {
        this.a = a;
    }

    public Object clone() {
        try {
            return super.clone();
        } catch(CloneNotSupportedException e) {
            System.out.println("Cloning not allowed.");
            return this;
        }
    } 
}

これをテストできます::

public class Test {

    public static void main (String args[]) {
        SomeType a = new SomeType();
        SomeType b = (SomeType) a.clone();
        if ( a == b ) {
            System.out.println( "yes" );
        } else {
            System.out.println( "no" );
        }
    }

}

はい、オブジェクトの種類が異なる場合はリフレクションを試すことができますが、属性の名前は同じでなければならないことに注意してください

これがリフレクションを使用した答えです。このクラスを使用すると、メソッドと属性の名前が同じである限り、タイプに関係なく、あるオブジェクトから別のオブジェクトにすべてのパラメーターを渡すことができます。

package co.com;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class SetAttributes {

public static String capitalize( String word ) {
    return Character.toUpperCase( word.charAt( 0 ) ) + word.substring( 1 );
}

public static void setAttributes( Object from, Object to ) {
    Field [] fieldsFrom = from.getClass().getDeclaredFields();
    Field [] fielsdTo = to.getClass().getDeclaredFields();
    for (Field fieldFrom: fieldsFrom) {
        for (Field fieldTo: fielsdTo) {
            if ( fieldFrom.getName().equals( fieldTo.getName() ) ) {
                try {
                    Method [] methodsTo = to.getClass().getDeclaredMethods();
                    for ( Method methodTo: methodsTo ) {
                        if ( methodTo.getName().equals( "set" + capitalize( capitalize( fieldTo.getName() ) ) ) ) {
                            Method methodFrom = from.getClass().getDeclaredMethod( "get" + capitalize( fieldFrom.getName() ), null );
                            methodTo.invoke(to, methodFrom.invoke( from, null ) );
                            break;
                        }
                    }
                } catch (SecurityException e) {
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
            System.err.println( fieldFrom );
        }
    }
}

public static void main (String args[]) {
    SomeType a = new SomeType();
    SomeType b = new SomeType();
    a.setA( "This" );
    setAttributes( a, b );
    System.err.println( b.getA() );
}

}
于 2013-02-02T22:18:46.747 に答える