i have a class that is used widely in my project as some sort of field holder. Something like:
class A
{
private String field = null;
private String field2 = null;
private String field3 = null;
// and its generic Getters and Setters
}
In certain part of code i need add additional fields to this class. So i did this
class B extends A
{
private String fieldInB = null;
// and its Getters and Setters
}
in my function i thought i could easily do
public void foo( A a )
{
B b = (B)a;
}
And i could have all the fields written in aobject and i could easily set only field in b and use it. This seams like a common problem, but i just don't know how to do it except with an very ugly approach:
public B( A a )
{
// copy all the fields one at the time
}
You areconfusing different parts of Java:
B b = (B)a;
this is classical class cast, but to work with B class object you need:
1. be sure that a is of B class (check it with instanceof java keyword:
if (a instanceof B) {
B b = (B) a;
}
2. or wrap a in B class object (create B class object with copying fields from a).
PS in most of Java coding conventions it is recommended to fill fields by concrete values only (and not fill with default JavaVM values - nulls)
Comfortable way to copy A class fields to new instance:
public A (A a) {
this.field = a.field;
this.field2 = a.field2;
this.field3 = a.field3;
}
and for B class:
public B (A a) {
super(a);
}
Another way - some libraries that will work with A class and B class as with beans. Sample of this libraries you can find in Toilal's answer
You could use Dozer. It allows to map bean property values from one bean class to another.
Hai john Actually i didn't get your exact requirement. I recon the way you have written this code is not right.
Private variable cant be inherited.If you need to extend values to your subclass you should have declared those variables as public.
public B(A a)
{
super.field=a.field;
super.field2=a.field2;
super.field3=a.field3;
}
Related
So imagine I have a simple class with three variables which are ultimately derived from another object. I could insert that other object in the constructor like:
public class A {
private int x;
private int y;
private List<> list;
public A(B b) {
this.x = b.getX();
this.y = b.getY();
this.list = b.getList();
}
}
public class B {
private int x;
private int y;
private int z;
private String string;
private Set<> set;
private List<> list;
//constructor, setters and getters
}
A colleague has suggested I should instead do the following:
public class A {
private B b;
public A(B b) {
this.b=b
}
}
Now in the application using their option will require a lot of refactoring from
a.getX() to a.getB().getX() or a.getList() to a.getB().getList() for example.
What I'm struggling to find is what is there some best practice defined in this scenario and why.
My argument is I don't want objects that use A to be coupled to any class structure imposed by B. I think my colleague is concerned that my constructor should not be accepting B as an argument only to call getters on it's variables within the constructor of A.
An alternative would be to use a factory or something to create A from B but that isn't really feasible with my use case. (In my specific use case A is being constructed in a HQL query and B is an Entity class)
EDIT:
I typed this question out on my phone but realise I missed some details so will add them here.
A consists of a subset of properties from B. A also consists of a subset of properties of another class C. The properties of C are currently individually assigned in the constructor in what you would consider a normal manner (because there are only a few). Because A takes a lot of properties from B I am inserting it in the manner illustrated above.
B and C are Entity classes that represent a row from two separate (but related) tables.
A is a class which is we use to do some business logic with somewhere else.
Maybe this is what you are looking for. A is a more general type and B is a more specialize type of A. For example, a Person class and a Student class.
public class A {
private int x;
private int y;
private List<> list;
public A(int x, int y, List<> list) {
this.x = x;
this.y = y;
this.list = b.getList();
}
}
public class B extends A {
private int z;
private String string;
private Set<> set;
public B(int x, int y, List<> list, String string, Set<> set){
super(x,y,list);
this.string = string;
this.set = set;
}
}
With all the information that you have given, your colleague's suggestion of having B object as a class field of A is a bad design. As well as passing B on the A constructor.
The main problem here is on the A class constructor, not it's field.
Passing B object directly to A constructor is a bad design/practice even if A takes a lot of properties from B. If someone were to construct an A object that takes B as an argument, most of the time they would assume that A uses B or that they have a strong relationship. If your concern here is avoiding a lengthy constructor, then you're better off using A setters to take the B properties as shown below:
A aClass = new A();
aclass.setX(bClass.getX());
aclass.setY(bClass.getY());
Another way is creating a method in class A that takes required properties from B by taking B as an argument like:
public class A {
\\fields
public void setRequiredPropertiesFromBClass(B bClass) {
this.x = bClass.getX();
\\\other getters
}
}
That way the intent of your code is clear, which is A needs certain properties from B not B itself. The example above can still be improved. I couldn't think of much better method name since I don't really know the complete implementations of these classes. Lastly, you mentioned that B and C are related so you can turn the method into a generic one so it can take B and C.
If all of these suggestions are still not helpful. Just search for Transfer Object Pattern on the internet.
So I resolved this by creating a static mapper like this;
public class Mapper {
public static A mapToA(B b) {
return A.builder()
.x(b.getX())
.y(b.getY())
.list(b.getList())
.build();
}
}
Obviously the mapper holds the relationship between A and B (and in my case also C).
As mentioned above A is a DTO and B and C are database entities. The existing application was actually quite poorly written with the Repository interfaces directly returning the DTO A as part of a HQL query. I changed these to directly return B and C and then mapped these to A in the service classes.
I came across some code written in Scala that has the following structure
// a.scala
object A {
def apply(arg: String) = {
new A(arg)
}
// declare a bunch of constants
val SOME_CONSTANT_A = "some_constant_a"
}
class A {
// define functions that use SOME_CONSTANT_A and the other constants.
}
We now have b.scala which is has object B with different constants and the exact same body of class A duplicated as class B(class B uses the constants inside object B).
What is the best way to refactor this code? I'd like to just have a single class, and have its behavior change based on the object somehow.
Definition:
class Base(private val constant: String) {
def printConstant(): Unit = println(constant)
}
class A extends Base("constant_for_a")
class B extends Base("constant_for_b")
Usage:
val a1 = new A()
a1.printConstant()
// constant_for_a
val b1 = new B()
b1.printConstant()
// constant_for_b
I have following classes
class A {
private Long id
private List<B> listB;
private C c;
...
}
class B {
private Long id
private A a;
private List<D> listD;
...
}
class C {
private Long id
private A a;
...
}
class D {
private Long id
private B b;
...
}
I need a copy of A, include all of it's properties except all id column.
I have 2 solutions:
1. Clone each object and set all of the ids null;
2. Make a constructor like this:
public A (A a){
//copy all properties except id
this.xxx = a.xxx;
...
}
But i need write so much code for this function, any one has some better method to implement this function?
Thanks a lot.
When you are saying Deep cloning of the object particularly the one of type Class A where you have an instance variable of a container type, you have below two widely known ways:
1) You Serialize and Deserialize the object.
2) You traverse through each method and call clone explicitely.
For first implementation, you may mark the id fields as transient and that should solve your purpose.
For second approach, you may override the clone method in each class where you set the id field as 0/-1) and call super.clone()
You can use Mapstruct , it's a powerful mapping library where you can configure all the fields exclusions for your specific class or nested class, without having to write all the getters/setters manually.
I personally use it for deep cloning jpa entities excluding ids or auditable fields.
Ex:
#Mapping(target="id",ignore=true")
EntityA cloneEntityAWithoutId(EntityA origin);
Mapstruct will generate for you the implementations using getters and setters of the EntityA, excluding the id field.
Obviously is a lot configurable, see the documentation I shared above.
I am trying to create a GWT Editor for a bean Object, which has two fields of another Object type, therefore I want sub-editors for those fields. The problem is that I am quite new to the editors framework, and I don't really get the idea of all those Editor interfaces out there.
Please advise of the best solution. My ideas were the following: using drivers of sub-editors to pass data to main editor driver; or use some sort of CompositeEditor (but I didn't know what to do with overridden methods...).
Here's a sample code:
public class A {
String s1, s2;
Integer i;
Double d;
B ba, bb;
}
public class B {
BigDecimal a, b;
}
//sub-editor
public class BEditor extends Composite implements Editor<B> {
interface BDriver extends BeanEditorDriver<B, BEditor> {
}
//implements HasEditorErrors interface
ValueBoxEditorDecorator<BigDecimal> a, b;
}
//main editor
public class AEditor extends Composite implements Editor<A> {
interface ADriver extends BeanEditorDriver<A, AEditor> {
}
private ADriver driver = GWT.create(ADriver.class);
ValueBoxEditorDecorator<String> s1, s2;
ValueBoxEditorDecorator<Integer> i;
ValueBoxEditorDecorator<Double> d;
BEditor ba, bb;
public AEditor() {
driver.initialize(this);
driver.edit(new A());
}
//called when the editor form is submitted
public void onSubmit() {
driver.clearErrors();
A a = driver.flush();
// A has both B fields = null
// AEditor successfully displays validation errors,
// but BEditors do not display errors, nor does
// ADriver get any errors from BEditor
}
}
}
When you create the VehiculeDTO, also create B subclasses :
A a = new A();
a.setBa(new B());
a.setBb(new B());
driver.edit(a);
Here are some guidelines from my experiences using the Editor Framework, both personally, and also in industry. I have tried my best to make them relevant to your example.
Identify your "top-level" editor. In your case, it would be AEditor - in most other cases, it would be a view. Have the designated widget implement the Editor interface, with type param = your backing object (which you have done correctly).
Ensure your backing object A includes getters and setters and the fields are private. You have left them with default access which I don't think is a good idea.
Ensure your top level widget contains a sub-editor for each of the fields in A. They should share the same name as the corresponding field in A, or be annotated with #Path to indicate which field they relate to.
Your sub-editors should never have their own driver interface. They should either implement LeafValueEditor, ValueAwareEditor etc or an adapter interface such as IsEditor
In the constructor for your top level editor (here, AEditor), you need to initialise the driver and backing object:
ADriver driver = GWT.create(ADriver.class);
public AEditor {
driver.initialize(this);
driver.edit(new A());
}
When you save, you should be calling driver.flush() to move the data from the top level editor into the backing object. Conversely, when you load, you should be calling driver.edit() with the backing object you wish to load
I have put up some Gists to demonstrate LeafValueEditor and IsEditor, in case you need help changing your sub-editor:
LeafValueEditor
IsEditor
I would like to do something like this:
Class A
Class B extends A
Class C extends A
B b = new B();
C c = new C();
b->setField("foo");
c->getField; //return "foo"
Is it somehow possible to implement these classes?
I need it for persistance in hibernate, to make entity split into two entites and have each in its own table. And I need to have some fields same (id, some FK, some values). So I would like to set these fields in one subclass and have the same values in second subclass. All subclasses need to have/share exactly same value.
Any idea?
Regardless of whether that is possible or not from a Java perspective (it is, but in a round-about way), it's not the correct way to handle what you require. If you're using foreign keys and update a value in some persisted entity, the corresponding value should be updated in the entities that use it as a foreign key. Just let JPA/Hibernate take care of this for you. I suggest you read up on the Java Persistence API in the Java EE Tutorial as well as the Hibernate guide to learn what it does and how data shared/divided across different entity classes and/or tables should be handled.
EDIT: since everyone keeps hammering on about static fields which is entirely not what the OP wants, I'll provide a sample of how I'd do this...
public class Key {
private String value;
public Key(final String value) {
this.value = vale;
}
public String getValue() {
return value;
}
public void setValue(final String value) {
this.value = value;
}
}
public class A {
private final Key field;
public A(final Key field) {
this.field = field;
}
public setField(final String value) {
field.setValue(value);
}
}
public class B {
private final Key field;
public B(final Key field) {
this.field = field;
}
public setField(final String value) {
field.setValue(value);
}
}
//When using...
Key k = new Key("value");
A a = new A(k);
B b = new B(k);
But like I said, this is only a solution on Java level but won't work properly in the context of persistance. You need to read up on the use of primary and foreign keys with regards to JPA and Hibernate. Judging from the notation used in the original question I'd say the poster comes from a non-Java background, therefor it is important that he learns how to properly use these technologies before accidentally reinventing the wheel.
you can use below code:
public class A {
private static String field;
public static String getField() {
return field;
}
public static void setField(String field) {
A.field = field;
}
}
public class B extends A{
}
public class C extends A{
}
public class Test {
public static void main(String[] args){
B.setField("Thank you"); // or
new B().setField("Thank you");
System.out.println(C.getField()); // or
System.out.println(new C().getField());
// it will work for object and for class as well
}
}
output : Thank you
You can try making your field static. Then you will be able to access it this way.
If the field is static, then they will share the same value. Not to up on Hibernate, so I am not sure if that changes anything from a persistence standpoint.
Hibernate would normally not manage static fields. In that case, you could just add a static getter and setter to class A. If you don't shadow them in a subclass (there's no overriding of static methods) calling C.setField("foo"), A.setField("foo"), c.setField("foo") (note that c is an instance) etc. will all be calls to the same method.
In case you want to provide common properties for your entities, but the entities can have different values, try to use the #MappedSuperClass annotation.