问题
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