How to prune an object of some of its fields in Java?

半世苍凉 提交于 2019-12-18 09:45:00

问题


Suppose we have an object obj of type Object such that System.out.println(obj) produces {a=Some text, b=Some more text, c=Even more text}.

Now we want to make a new object obj2 that is just {a=Some text} (i.e., the fields b and c are pruned from obj). So we define a class A as follows:

class A {
    String a;
}

Then we initialize obj2 as follows:

A obj2 = (A) obj.

Unfortunately, I get a run time error when doing this.

Question: How do we define obj2 as outlined above?


回答1:


Assume that you have three fields f1,f2,f3 in class A

Create a new class B with field f1

Declare a method in class A like this

public B getTrimmedObject()

Set required fields of B from A.

e.g. set f1 and return B Object

Other way : use composition over inheritance.B will become member of A and you can simply get B from A. In this case split fields between A and B and avoid duplication.

f1 will be part of B and B,f2,f3 will be part of A. A Constructor will set f1 value through B and f2,f3 are set with normal initialization

EDIT: example code:

public class A{
    private B b;
    private String f2;
    private String f3;

    public A(String f1,String f2,String f3){
        b = new B(f1);
        this.f2 = f2;
        this.f3 = f3;
        System.out.println("In A->B:"+getB().getF1()+":A:f2:"+f2+":A:f3:"+f3);
    }
    public B getB(){
        return this.b;
    }
    public static void main(String args[]){
        if (args.length < 3) {
            System.out.println("Usage: java A str1 str2 str3");
            return;
        }
        A a = new A(args[0],args[1],args[2]);

    }

}
class B{
    private String f1;
    public B(String f1){
        this.f1 = f1;
    }
    public String getF1(){
        return this.f1;
    }
}



java A apple banana camel

 In A->B:apple:A:f2:banana:A:f3:camel



回答2:


The reason you are getting an exception is because obj is only of type Object; you can't "magically" turn it into an A so it fits into obj2. In Java, you can only cast an Object to a type it is already; you can't make something that isn't an A an A. Instead, you have to manually copy the properties, i.e. set obj2.a to obj.a.

One alternative to assigning obj2.a = obj.a is to make both obj and obj2 of type A, with obj also being a more specific type B. For example, say you were to define the A class as follows:

public class A {

    public String a = "Some text";

}

You could then define B as:

public class B extends A {

    public String b = "Some more text";
    public String c = "Even more text";

}

Finally, you can create your objects as such:

B obj = new B();
A obj2 = obj;

System.out.println(obj2.a); // Prints "Some text"
System.out.println(obj2.b); // Throws an error

Please note that in the second method, obj2 still has the properties b and c; they are just not accessible.




回答3:


In java every object is an Object. Therefore obj must be an Object. But it doesn't mean that obj is only an Object. Definitely, if you get some readable result for System.out.println(obj) then obj is extended from another class.

It is not type A because A a = (A)obj gives an error. You can see the class name of obj using:

System.out.println(obj.getClass().getName());

Let's assume obj is from class B. There are some things to do to do what you want.

If you can change the definition of B then you can extend class B from class A. Then A a = (A)obj; will work.

class B extends A{
    ...
}

But if you print a you will not get your desired output.

You can change class A.

class A{
    private B b;
    public A(B b){
        this.b = b;
    }

    @Override
    public String toString() {
        return "{a=" + b.a + "}";
    }
}

Then you have to create A a = new A(obj);. You can't cast this. But if you print a you will get your desired output.

Hope this might be helpful!!



来源:https://stackoverflow.com/questions/34280716/how-to-prune-an-object-of-some-of-its-fields-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!