How can i get the object enhanced by cglib - java

I'm using spring and cglib and i have those classes:
public class A {
.
.
private Souscripteur souscripteur;
private List<B> contrat;
// getter and setter
}
public class B {
.
.
private Souscripteur souscripteur;
//getter and setter
}
and the Class A and B have the same souscripteur, so when i load the Class A and try to load the class B, i get the Souscripteur of the class B EnhancerByCGLIB.
For that, when i try to do this :
if(b.getSouscriteur() instanceof PersonnePhysique) {
//do something
} else {
//do nothing
}
when i inspect the code, the object enhanced is a PersonnePhysique, but if(b.getSouscriteur() instanceof PersonnePhysique) return false
My class PersonnePhysique is like this :
public class PersonnePhysique extends Souscriteur {
//
}

Hibernate generates proxies based on the declared, expected type (Souscripteur), so you'll get a lazy-loaded proxy extending Souscripteur - hence, no PersonnePhysique in the instanceof sense.
You have to avoid testing concrete types here, and rather call polymorphic methods on your entities (which is, by the way, more object-oriented).
Your use case, provided you are calling a method doSomething(), would become:
b.getSouscriteur().doSomething()
with the following implementations:
public class Souscripteur {
public void doSomething() {
// do nothing
}
}
public class PersonnePhysique extends Souscripteur {
#Override
public void doSomething() {
// do something here
}
}

Related

Java invoke child method from parent object

I've got next situation:
There is an abstract class
public abstract class SuperClass {
public abstract void getString();
public abstract void method2();
}
public class InheritClass1 extends SuperClass {
#Override
public void getString(){...};
#Override
public void method2(){...};
}
public class InheritClass2 extends SuperClass {
#Override
public void getString{...};
#Override
public void method2(){...};
public void customMethod(){...};
}
There is another class that has a method that accepts SuperClass object as an argument. Depending on what kind of String is returned from getString I perform different actions. My case is that I am trying to call a child method while the object is of parent class:
public class Processor {
public String method(SuperClass type) {
switch (type.getString()) {
case "1":
return "OK"
case "2":
return ((InheritClass2) type).customMethod()
}
}
I do understand that this is BAD DESIGN, could you please help me with finding the best solution for this problem. Maybe generics are suitable in this case somehow. Also the thing is that customMethod() should be a part of not all classes.
Since only some (sub)classes implements customMethod, I would suggest to create an interface that contains this method:
public interface CustomInterface {
public String customMethod();
}
Your SuperClass can then remain just as it is. Only the subclasses/child classes that have customMethod, would then extend your SuperClass as well as implement this CustomInterface. This way, the child classes that do not implement CustomMethod (does not have the method in their class, such as InheritClass1 in your example), also remain just as they are.
Only child classes that have CustomMethod, such as InheritClass2 would then need to change slightly by saying it implements this new interface:
public class InheritClass2 extends SuperClass implements CustomInteface {
// the rest stays the same
}
Then in the section where you want to do the casting, you rather do the following:
public class Processor {
public String method(SuperClass type) {
switch (type.getString()) {
case "1":
return "OK"
case "2":
String s = "";
if (type instance of CustomInterface) {
s = (CustomInterface type).customMethod();
}
return s;
}
}
}
Using the interface in this way will help that you can implement all child classes and not just one as implementing the CustomInterface, and thus, all child classes will work with using instanceof and casting to the interface to call customMethod() - you won't have to handle each child that needs this method separately.
NOTE: Your code is clearly simplified example, it is unclear if the getString() method is just returning an identifier of the child classes in order for you to know which ones you can cast and then call custom Method on... If this is the purpose of your switch and getString methods - to identify which types implement the customMethod() and to call that method, and for any child class that does not have that method to return just "OK" - then you could instead do the following:
public class SubClass1 extends SuperClass implements CustomInterface {
// other mehtods...
public String CustomMethod() { return "SomeString1"; }
}
public class SubClass2 extends SuperClass {
// other methods...
// this subclass does not have the CustomMethod()
}
public class SubClass3 extends SuperClass implements CustomInterface {
// other methods...
public String CustomMethod() { return "SomeString3"; }
}
Then your Processor could look like this:
public class Processor {
public String method(SuperClass type) {
return (type instanceof CustomInterface) ? ((CustomInterface) type).CustomMethod() : "OK";
}
public static void main(String[] args) {
Processor p = new Processor();
SuperClass obj1 = new SubClass1();
SuperClass obj2 = new SubClass2();
SuperClass obj3 = new SubClass3();
System.out.println(p.method(obj1)); // prints: "SomeString1"
System.out.println(p.method(obj2)); // prints: "OK"
System.out.println(p.method(obj3)); // prints: "SomeString3"
}
}
If you don't understand the ternary operator then you can read about it here That's the condition ? exprTrue : exprFalse syntax. It's a short if else statement basically.
You can create an interface, with default custom method implementation, like:
interface A {
default String customMethod() {
return "";
}
}
And abstract class will implement this interface:
public abstract class SupperClass implements A {
public abstract String getString();
public abstract void method2();
}
Bad design will cause you to get bad answers. If you don't want to cast your object to a child object. You could use reflection.
import java.lang.reflect.Method;
public class Processor {
public String method(SuperClass type) {
Method[] methods = type.getClass().getMethods();
for (Method m : methods) {
if (m.getName().equals("customMethod")) {
try {
return m.invoke(type);
} catch (Exception ex) {
// throw
}
}
}
return "OK";
}
}
Depending on your design you could apply:
if (type instanceof InheritClass2.class) return type.customMethod();
or
if (type.getClass() == InheritClass2.class) return type.customMethod();

Can a super class method implementation depend on child class field

I am in a situation as follows.
I have an interface A which is inherited by class B,C,D (B,C,D implements A).
public interface A{
public String someMethod();
}
class B implements A{
ObjectType1 model;
#Override
public String someMethod(){
if(model instanceof X){
System.out.print(true);
}
}
}
class C implements A{
ObjectType2 model;
#Override
public String someMethod(){
if(model instanceof X){
System.out.print(true);
}
}
class D implements A{
ObjectType3 model;
#Override
public String someMethod(){
if(model instanceof X){
System.out.print(true);
}
}
As you can see all method implementations are the same. So I am duplicating code. My plan was to move the method to A and make A an abstract class. But the problem is my method depends on the model field. So what would be my options to make this code better?
bdw class A,B,C extends and implements other classes too.
EDIT
modification in code. check field
I don't see any problem related to the model field transforming the interface A into an abstract class.
There is no need to reimplement the method in the subclasses if it is the same, unless you want to change its behavior (override it).
public abstract class A {
// Make it protected so it can accessible by subclasses
protected Object model;
// Common behavior that will be inherited by subclasses
public String someMethod() {
if (model instanceof X) {
return "x";
} else {
return "not x";
}
}
}
public class B extends A {
// Subclasses may access superclasses fields if protected or public.
public void someOtherMethod() {
System.out.println(super.model.toString());
}
}
public class C extends A {
// You may wish to override a parent's method behavior
#Override
public String someMethod() {
return "subclass implements it different";
}
}
For your new code example, if you really want to do that in a procedural way you can create an abstract superclass ObjectType and then it will be accessible for the parent as well.
However I wouldn't do that. It seems to me that in doing so is the very opposite of what object orientation tries to solve.
By using a subclass to define the behavior, you wouldn't need to do it in a procedural logic. That's precisely then point of using objects, inheritance and overriding/implementing behavior as needed.
Create a parent class A with said field, and said function. Have the other classes extend A. No need to override them if they function the same.
To deduplicate, you can either make A an abstract class and move the implementation of the method and the field there, or create an abstract class, say E, that implements the interface with that method and field and then have B, C and D extend that class E.
For the more general question of depending on a subclass's field, you can create an abstract method getModel which the subclasses decide how to implement -- by returning a model field or doing something else.
If you are using java 8 you could use default method in interface A, with a getter method for model.
public interface A{
default public String someMethod() {
if(getModel() instanceof X){
System.out.print(true);
}
}
public Object model getModel();
}
Then implement getModel method in all child interfaces.
If you're going to do this you must have model to be of the same (basic) type in all derived objects. If it were of the same type there's a case for putting the model to a base class. Anyway if they are of different derived types you would need to have an accessor to get it.
interface B {
BaseModel getModel();
default public strict doSomething() {
BaseModel m = getModel();
// do something with m
}
}
class D implements B {
DerivedModel model;
public getModel() {
return model;
}
}
If I was given a chance to refactor it, I will follow below approach, leveraging Java 8 Default Methods:
interface A {
default String someMethod(X objectType) {
if (objectType instanceof X) {
System.out.println(true);
}
// return something, for now returning class
return objectType.getClass().toString();
}
}
class B implements A {
#Override
public String someMethod(X objectType) {
if (objectType instanceof X) {
System.out.println(true);
}
// return "Hello"
return "Hello";
}
}
class C implements A {}
class D implements A {}
Usage:
public class Main implements A {
public static void main(String[] args) {
B b = new B();
C c = new C();
D d = new D();
Main main = new Main();
main.call(b);
main.call(c);
main.call(d);
}
public void call(A clazz) {
ObjectType1 objectType1 = new ObjectType1();
String type = clazz.someMethod(objectType1);
System.out.println(type);
}
}
interface X {
}
class ObjectType1 implements X {
}

Create a parent class that returns child class objects

I'm building a base/parent class in Java that's going to have several methods for creating the class itself and I'm wondering if there's any way to have the parent class return instances of the child class instead of returning instances of the parent class that then have to be cast to the child?
For example, here's my parent class:
public abstract class SFObject
{
// Variables
protected String mID;
protected String mName;
// Function called to create ourselves from a DiffObject
public abstract SFObject CreateFromDiffObject(DiffObject object);
// Function called to create a list of ourselves from a query
public List<SFObject> CreateListFromQuery(Connection connection, String query)
{
// Run the query and loop through the results
ArrayList<SFObject> objects = new ArrayList<SFObject>();
for (DiffObject object : connection.Query(query))
objects.add(CreateFromDiffObject(object));
return objects;
}
}
If I create a child class based on my SFObject class, the two functions in my child class will still return an SFObject (that needs to be cast to my child class type) or a list of SFObjects (that need to be individually cast to my child class type). Is there any way (maybe using Reflections) to have my child class returns instances of itself as itself and not as SFObjects?
What you are describing is known as a covariant return type.
Class A {
A getInstance() { ... }
}
Class B extends A {
#Override
B getInstance() { ... }
}
This has been allowed since Java 1.5.
If you place the child class object inside of the parent object, methods called will run from the child class. But it will look like the parent object on the surface
public class A{
method 1(){//do some stuff}
method 2(){//do some stuff}
}
public class B extends A{
method 1(){super.method 1()
//do some other stuff}
method 2(){super.method 2()
//do some other stuff}
}
public class test{
A a = new B();
//any method called on 'a' will come from the child class
// But 'a' is the parent object
}
Not sure if I really understand your Problem correct because it sounds to me lke this:
class p
{
public static p createParent()
{
return new p();
}
public static c createChild()
{
return new c();
}
}
Of course it doesn't have to be static, just thought of some kind of factory.
Exactly for this functionalities are proposed the factory methods, as you already implemented. In the child class you can change the return type without offending the method declaration. A sample for your case would be something like:
public abstract class SFObject {
// Variables
protected String mID;
protected String mName;
// Function called to create ourselves from a DiffObject
public abstract SFObject CreateFromDiffObject(DiffObject object);
// Function called to create a list of ourselves from a query
public List<? extends SFObject> CreateListFromQuery(Connection connection, String query) {
// Run the query and loop through the results
ArrayList<SFObject> objects = new ArrayList<SFObject>();
for (DiffObject object : connection.Query(query))
objects.add(CreateFromDiffObject(object));
return objects;
}
}
class SFObjectChild extends SFObject {
#Override
public SFObjectChild CreateFromDiffObject(DiffObject object) {
SFObjectChild result = new SFObjectChild();
//...
return result;
}
#Override
public List<? extends SFObjectChild> CreateListFromQuery(Connection connection,
String query) {
return null;//..;
}
}
This is acceptable because the return type of the children class is still a kind of (hierarchical speaking) the parent.
Be aware of java code conventions (methods in camel case starting with low, e.g. createFromDiffObject).

Super class which uses the values from children

I wanted to implement a method in a abstract class that is called by the inherited classes and uses their values.
For instance:
abstract class MyClass{
String value = "myClass";
void foo(){System.out.println(this.value);}
}
public class childClass{
String value="childClass";
void foo(){super.foo();}
}
public static void main(String[] args){
new childClass.foo();
}
This will output "myClass" but what I really want is to output "childClass". This is so I can implement a "general" method in a class that when extended by other classes it will use the values from those classes.
I could pass the values as function arguments but I wanted to know if it would be possible to implement the "architecture" I've described.
A super method called by the inherited class which uses the values from the caller not itself, this without passing the values by arguments.
You could do something like this:
abstract class MyClass {
protected String myValue() {
return "MyClass";
}
final void foo() {
System.out.println(myValue());
}
}
public class ChildClass extends MyClass {
#Override
protected String myValue() {
return "ChildClass";
}
}
and so on
This is a place where composition is better than inheritance
public class Doer{
private Doee doee;
public Doer(Doee doee){
this.doee = doee;
}
public void foo(){
System.out.println(doee.value);
}
}
public abstract class Doee{
public String value="myClass"
}
public ChildDoee extends Doee{
public String= "childClass"
}
...
//Excerpt from factory
new Doer(new ChildDoee);
I believe you are asking whether this is possible:
public class MyClass {
void foo() {
if (this instanceof childClass) // do stuff for childClass
else if (this intanceof anotherChildClass) // do stuff for that one
}
}
So the answer is "yes, it's doable", but very much advised against as it a) tries to reimplement polymorphism instead of using it and b) violates the separation between abstract and concrete classes.
You simply want value in MyClass to be different for an instance of childClass.
To do this, change the value in the childClass constructor:
public class childClass {
public childClass() {
value = "childClass";
}
}
Edited:
If you can't override/replace the constructor(s), add an instance block (which gets executed after the constructor, even an undeclared "default" constructor):
public class childClass {
{
value = "childClass";
}
}

Initialize supertype members based on subtype information

I have the following situation:
public abstract class A {
private Object superMember;
public A() {
superMember = initializeSuperMember();
// some additional checks and stuff based on the initialization of superMember (***)
}
protected abstract Object initializeSuperMember();
}
class B extends A {
private Object subMember;
public B(Object subMember) {
super();
subMember = subMember;
}
protected Object initializeSuperMember() {
// doesn't matter what method is called on subMember, just that there is an access on it
return subMember.get(); // => NPE
}
}
The problem is that I get a NPE on a new object B creation.
I know I can avoid this by calling an initializeSuperMember() after I assign the subMember content in the subclass constructor but it would mean I have to do this for each of the subclasses(marked * in the code).
And since I have to call super() as the first thing in the subclass constructor I can't initialize subMember before the call to super().
Anyone care to tell me if there's a better way to do this or if I am trying to do something alltogether wrong?
Two problems:
First, you should never call an overrideable member function from a constructor, for just the reason you discovered. See this thread for a nice discussion of the issue, including alternative approaches.
Second, in the constructor for B, you need:
this.subMember = subMember;
The constructor parameter name masks the field name, so you need this. to refer to the field.
Follow the chain of invocation:
You invoke the B() constructor.
It invokes the A() constructor.
The A() constructor invokes the overridden abstract methot
The method B#initializeSuperMember() references subMember, which has not yet been initialized. NPE.
It is never valid to do what you have done.
Also, it is not clear what you are trying to accomplish. You should ask a separate question explaining what your goal is.
Hum, this code does not look good and in all likelyhood this is a sign of a bad situation. But there are some tricks that can help you do what you want, using a factory method like this:
public static abstract class A {
public abstract Object createObject();
}
public static abstract class B extends A {
private Object member;
public B(Object member) {
super();
this.member = member;
}
}
public static B createB(final Object member) {
return new B(member) {
#Override
public Object createObject() {
return member.getClass();
}
};
}
The problem is when you call super(), the subMember is not initialized yet. You need to pass subMemeber as a parameter.
public abstract class A {
public A (Object subMember) {
// initialize here
}
}
class B extends A {
public B (Object subMember) {
super(subMember);
// do your other things
}
}
Since you don't want to have subMember in the abstract class, another approach is to override the getter.
public abstract class A {
public abstract Object getSuperMember();
protected void checkSuperMember() {
// check if the supberMember is fine
}
}
public class B extends A {
private Object subMember;
public B(Object subMember) {
super();
this.subMember = subMember;
checkSuperMemeber();
}
#Override
public Object getSuperMember() {
return subMember.get();
}
}
I hope this can remove your duplicate code as well.

Categories