Function the uses an object relying in two different packages - java

I have the sama java object TestData in to packages (A & B). I have made a function that processes the object for a standard business functionality.
CommonFunc.java:
import A.TestData ;
class CommonFunc
{
/// .....
public static TestData processTestData(Date d1, String s1){
TestData testData = new TestData ();
/// set some testData porperties based on d1 and s1
/// e.g : testData.setInitialDate(d1);
return testData ;
}
}
The problem here is that the compiler has to load the object from one of the packages lets say package (A), so when I expect the data to be returned to a local variable from package (B) I get incompatible type error :
File using B TestData and needs to call the function processTestData:
import B.TestData;
// ...
TestData obj = CommonFunc.processTestData(new Date(), "test");
// ...
Is there a way to overcome this problem keeping a common function for both?

Is there a way to overcome this problem keeping a common function for both?
No and yes. On the general case, you cannot.
But you can, IFF you can make the two classes adopt the same interface, with the common methods declared in the same interface. See below, with apologies for the change in the class names:
interface C {
public Date getA();
public void setA(Date a);
}
interface C_Factory <X extends C> {
X createInstance();
}
class C1 implements C {
Date a;
int b;
public C1() {
super();
}
public Date getA() { return a; }
public void setA(Date a) { this.a = a; }
public int getB() { return b; }
public void setB(int b) { this.b = b; }
}
class C2 implements C {
Date a;
float b;
public C2() {
super();
}
public Date getA() { return a; }
public void setA(Date a) { this.a = a; }
public float getB() { return b; }
public void setB(float b) { this.b = b; }
}
public class CommonFunc {
// You need this extra param to create instances----
// V
static <X extends C> X doSomething(Date d, Class<X> clazz)
throws InstantiationException, IllegalAccessException
// You'll have to accept those exceptions as well
{
// the next statement uses clazz as a factory for new X instances
// As such, you can abstract the method further and use
// a custom Factory class instead.
X toret=clazz.newInstance();
toret.setA(d);
// something else
return toret;
}
// A custom factory variant of the above
static <X extends C> X doSomething(Date d, C_Factory<X> factory)
{
X toret=factory.createInstance();
toret.setA(d);
// something else
return toret;
}
static public void main(String[] args) {
try {
C1 c1=doSomething(new Date(), C1.class);
C2 c2=doSomething(new Date(), C2.class);
} catch (InstantiationException | IllegalAccessException e) {
// Should not happen
e.printStackTrace();
}
}
}

I do not see how it is possible in the above example you have posted, The best way out is to make the TestData an interface and have implementations in 2 packages. Then, to decide whether to return A TestDataImpl or B TestDataImpl, take another parameter in the processData, for simplicity, let us say a boolean. Based on true or false instantiate A TestDataImpl or B TestDataImpl and return the same. Where the return type of processData is the interface type
This is probably would be the most straightforward way of reusing the processData method.

Related

Method returning as interface

Consider this example:
I have 3 interfaces: A, B, C, with methods a(), b(), c(); extending a base interface Intf;
I have a enum with options MyEnum.A, MyEnum.B, MyEnum.C;
I have a class extending this 3 interfaces: X implements A, B, C;
There is a way to implement a method in X like this;
public <T extends Intf> T getType (MyEnum enum)
and the result is the interface A, B or C, that is, accessing only method a(), b() or c()?
EDIT: I want to use it on a builder with fluent api:
X var = X.getType(MyEnum.A).a("value").build();
or
X var = X.getType(MyEnum.B).b("value").build();
but never
X var = X.getType(MyEnum.A).b("value").build(); //ERROR
You could dispatch the enum value, and return a matching instance, as #GhostCat suggested.
You could also invert the lookup, so each enum value provides an appropriate instance of Intf:
Variant 1: singleton instance per enum value
public enum MyEnum {
A(new AImpl()),
B(new BImpl()),
C(new CImpl());
private Intf instance;
MyEnum2(Intf instance) {
this.instance = instance;
}
public <T extends Intf> T getType() {
return (T) instance;
}
}
Variant 2: factory, creating new instances:
public enum MyEnum {
A(AImpl.class),
B(BImpl.class),
C(CImpl.class);
private Class<? extends Intf> type;
MyEnum(Class<? extends Intf> type) {
this.type = type;
}
public <T extends Intf> T getType() {
try {
return (T) type.newInstance();
} catch (InstantiationException | IllegalAccessException ex) {
throw new RuntimeException(ex.getMessage(), ex);
}
}
}
Usage:
A a = MyEnum.A.getType();
B b = MyEnum.B.getType();
C c = MyEnum.C.getType();
If I read your question correctly you want compile-time safety for
public <T extends Intf> T getType (MyEnum enum)
to return A for MyEnum.A, B for MyEnum.B etc.
You can achieve this compile-time safety if you make MyEnum class generic. This does now work with normal enums, but it works with old-fashioned "typesafe enum" pattern.
Assume we have three interfaces AA, BB , CC extending the base interface II:
public interface AA extends II { void a(); }
public interface BB extends II { void b(); }
public interface CC extends II { void c(); }
Now the class TT implements all of these interfaces:
public class TT implements AA, BB, CC {
#Override
public void a() { ... }
#Override
public void b() { ... }
#Override
public void c() { ... }
}
Now let EE be our generic pseudo-enum class, parameterized with some subtype of II:
public class EE<XX extends II> {
public static final EE<AA> A = new EE<AA>();
public static final EE<BB> B = new EE<BB>();
public static final EE<CC> C = new EE<CC>();
}
With these definitions the getType method can be declared as follows:
public <XX extends II> XX getType(EE<XX> enumVal)
This method may only return the type the type which parameterized the enumVal. Meaning
AA type = tt.getType(EE.A);
is valid but
BB type = tt.getType(EE.A);
is not.
One of the ways to implement the getType method would be delegate "conversion" of the TT instance to AA, BB or CC to the corresponding pseudo-enums:
public abstract class EE<XX extends II> {
public static final EE<AA> A = new EE<AA>() {
#Override
public <PP extends AA & BB & CC> AA convert(PP instance) {
return new AA() {
public void a() {
instance.a();
};
};
}
};
public static final EE<BB> B = new EE<BB>() {
#Override
public <PP extends AA & BB & CC> BB convert(PP instance) {
return new BB() {
public void b() {
instance.b();
};
};
}
};
public static final EE<CC> C = new EE<CC>() {
#Override
public <PP extends AA & BB & CC> CC convert(PP instance) {
return new CC() {
public void c() {
instance.c();
};
};
}
};
public abstract <PP extends AA & BB & CC> XX convert(PP instance);
}
You can also return instance directly, without wrapping in an anonymous inner class. But then the result can be force-casted to the other interfaces thus allowing access to other methods.
Finally, the implementation of getType is trivial:
public <XX extends II> XX getType(EE<XX> enumVal) {
return enumVal.convert(this);
}
From what I can see, the compiler won't allow
BB bb = tt.getType(EE.A);
Also
BB bb = (BB) tt.getType(EE.A);
bb.b();
won't work as in "produces ClassCastException in the runtime".
The disadvantages are a pseudo-enum construct and somewhat ugly implementation of convert.
Assuming that we are within class X, you have a local generic parameter, you could think of:
public <T extends Intf> T getType (MyEnum enumVal) {
if (enumVal == MyEnum.A) {
return (A) this;
if (enumVal == MyEnum.B) {
return (B) this;
But you don't gain anything from doing so. Those casts don't matter for the caller side.
Because there is nothing that the compiler could do for you here. You could write
A someA = whatever.getType(someEnum);
But you could as well write
B someB = whatever.getType(someEnum);
with the very same someEnum. And the compiler would be all happy.
If you want to achieve a gain on "compile time safety", you would have to somehow "connect" the argument type to the result type.

Implement a common function accepting argument of two different classes?

I have two classes A and B and they both have a common field in them, and I want to create a function in which if I pass Class A object then I want to set that common field value to the passed value and if I pass Class B object then I want to set that common field value to the passed value. Can anyone please tell me how can I do this, I am new to Java Generic Classes.
Otherwise I would have to make two different functions OR I would have to make an if and else which would decide that passed object belongs to which class ??
Class A
public class A{
int footer;
public void setFooter(int fo) {
footer = fo;
}
}
Class B
public class B{
int footer;
public void setFooter(int fo) {
footer = fo;
}
}
Class D
public class D{
public void change_footer(T generic_param, int value) {
generic_param.setFooter(value);
}
}
Class HelloWorld
public class HelloWorld{
public static void main(String []args){
Here I want to call
A a = new A();
new D().change_footer(a, 5);
B b = new B();
new D().change_footer(b, 5)
}
}
Thank You
And if I got all of the question wrong, and nor A nor B are generic, AND the type of field is fixed.
then you mean something like:
class D {
/*public <T extends Super> would be muuuch nicer here as well!*/
public /*static*/ <T> void change_footer(T obj, int data) {
//otherwise, you could just cast to Super...and set dat field.
if (obj instanceof A) {
((A) obj).setField(data);
} else if (obj instanceof B) {
((B) obj).setField(data);
} // else ... ?
}
}
Original answer:
Easy peasy (the "straight forward" implementation produces the desired results.):
class A<T> {
T daField;
public void setField(T pField) {
daField = pField;
}
public T getField() {
return daField;
}
}
class B<T> extends A {//empty
}
class Test {
public static void main(String... args) {
B<Object> testB1 = new B<>(); //
testB1.setField(new Object());
System.out.println(testB1.getField());
B<String> testB2 = new B<>();
testB2.setField("blah blah");
System.out.println(testB2.getField());
B<Integer> testB3 = new B<>();
testB3.setField(42);
System.out.println(testB3.getField());
}
}
System.out:
java.lang.Object#6d06d69c
blah blah
42
It get's (little) more complicated, when you want to instantiate Ts ...but still possible/other question. :)
Edit to your comment:
If there's only one common field, then why not:
/*abstract */class Super<T> {
T daField;
public void setField(T pField) {
daField = pField;
}
public T getField() {
return daField;
}
}
? ...and:
class A<T> extends Super { ... }
class B<T> extends Super { ... }

How to initialize a circular dependency (final fields referencing each other)?

How do you initialize this:
class A {
final B b;
A(B b) {
this.b = b;
}
}
class B {
final A a;
B(A a) {
this.a = a;
}
}
DI framework, reflection, better design?
Motivation and a use case (added):
My particular use case is simplifying field access in A's and B's sub-classes. So I'm injecting them to shortly reference them by fields in the derived classes without a need to declare explicitly in each sub-class.
There is also a recommendation on DI that objects should better be immutable: Guice best practices and anti-patterns.
You could use a factory method
class A {
final B b;
A(B b) {
this.b = b;
}
}
abstract class B {
final A a;
B() {
this.a = constructA();
}
protected abstract A constructA();
}
public class C {
public static void main(String []args){
new B(){
protected A constructA(){
return new A(this);
}
};
}
}
Though it may look dirty, but I prefer to replace one of the final references with Supplier (like one in Guava or Java 8) like:
class A {
final Supplier<B> b;
A(Supplier<B> b) {
this.b = b;
}
// keeping this constructor just for usability's sake
A(B b) {
this.b = ofInstance(b); // using Guava's Suppliers.ofInstance here
}
}
class B {
final A a;
B(A a) {
this.a = a;
}
}
public static void main(String[] args) {
// using MutableSupplier.create() static factory method
MutableSupplier<B> bRef = create();
A a = new A(bRef);
B b = bRef.set(new B(a));
}
where MutableSupplier looks somehow like the following:
import com.google.common.base.Supplier;
public class MutableSupplier<T> implements Supplier<T> {
private boolean valueWasSet;
private T value;
private MutableSupplier() {
}
#Override
public T get() {
if (!valueWasSet) {
throw new NullPointerException("Value has not been set yet");
}
return value;
}
public T set(final T value) {
if (valueWasSet) {
throw new IllegalStateException("Value has already been set and should not be reset");
}
this.value = value;
this.valueWasSet = true;
return value;
}
public static <T> MutableSupplier<T> create() {
return new MutableSupplier<T>();
}
}
I know that MutableSupplier's mutability looks super-ugly for immutability enthusiasts but I found that using it is more or less acceptable in such cases :)
What you are having is a circular dependency. The only way I can think of is to not declare the fields as final and have your dependency injected using setter injection instead of constructor injection.
A a = new A();
B b = new B();
a.setB(b);
b.setA(a);

Java Pattern to build object where any one field must be set?

I need to build objects of a class which has 3 fields: A, B and C. A valid object has at least one of A, B or C set by the user. I looked into the Builder Pattern, which is close to what I want, but only 1 field is made mandatory. I want that 1 field which must be set to be any one of the 3 that I have. Any suggestions?
My alternative is to use 7 constructors (for {A}, {B}, {C}, {A,B}, {B,C}, {A,C}, {A,B,C})
You can use a builder for that. Short example with only two fields instead of three:
public final class MyBuilder
{
private X a, b;
public MyBuilder withA(X a)
{
b = null;
this.a = a;
return this;
}
public MyBuilder withB(X b)
{
a = null;
this.b = b;
return this;
}
public MyClass build()
{
if (a == null && b == null)
barf(); // <-- throw exception here
// A and B inherit MyClass
return a != null ? new A(a) : new B(b);
}
}
You can force A, B, or C to be passed in the build() method:
class ValidBuilder {
public ValidBuilder withA(Object a) {}
public ValidBuilder withB(Object b) {}
public ValidBuilder withC(Object c) {}
public ValidObject buildA(Object a) { }
public ValidObject buildB(Object b) { }
public ValidObject buildC(Object c) { }
}

How do I control visibility to field in my Java classes?

How can I differentially control access to members of any class? Let's say I have three classes:-
Class A
{
int a;
int b;
}
Class B
{
Access to only 'a' and not 'b'
}
Class C
{
Access to only 'b' and not 'a'
}
One way would be to use aspect-oriented programming. You can check to see the accessing package or class and prohibit access.
AspectJ can be used to enforce that classes in the persistence tier are not accessed in the web tier, only from the service tier. Here's an example:
http://blog.jayway.com/2010/03/28/architectural-enforcement-with-aid-of-aspectj/
Interface time:
interface IHaveA { int a {get;set;} }
interface IHaveB { int b {get;set;} }
Class A : IHaveA, IHaveB
{
public int a {get;set;}
public int b {get; set;}
}
Class B
{
IHaveA _iHaveA;
C(IHaveA iHaveA)
{
_iHaveA = iHaveA;
}
}
Class C
{
IHaveB _iHaveB;
C(IHaveB iHaveB)
{
_iHaveB = iHaveB;
}
}
Then new up B and C like this:
static Main()
{
A a = new A();
B b = new B(a);
C c = new C(a);
}
Here is a really crude idea.
Have A have a function to take an observer derived from B, and another function to take an observer derived from A.
class A
{
int a;
int b;
void getAObserver(B bInstance);
void getBObserver(C cInstance);
}
Then have A can call functions such as aWasUpdated or bWasUpdated on the instances make the member a and b sort of psuedo public to the specific classes.
A really crude way of implementing this would be
Class A {
private int a ;
private int b ;
public int getA( Object obj) throws userDefinedIllegalAccessException {
//check if obj isInstance of B
// If yes return a
// else throw userDefinedIllegalAccessException
}
public int getB( Object obj) throws userDefinedIllegalAccessException {
//check if obj isInstance of c
// If yes return b
// else throw userDefinedIllegalAccessException
}
}
class B {
public void checkAccessValue() {
try{
A objA = new A() ;
System.out.println(objA.getA(this) ;
System.out.println(objA.getB(this) ;
}
catch(userDefinedIllegalAccessException udException){
}
}
}
class C {
public void checkAccessValue() {
try{
A objA = new A() ;
System.out.println(objA.getA(this) ;
System.out.println(objA.getB(this) ;
}
catch(userDefinedIllegalAccessException udException){
}
}
}

Categories

Resources