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