I have a problem that I cannot understand. First of all, I want to denote my structure:
I have a class named ClassMetadata. It is metadata about class values:
public class ClassMetadata<T extends Object> {
private int serviceId;
private int typeId;
private int revisionId;
#SuppressWarnings("rawtypes")
private Class clazz;
private ClassAttribute[] classAttributeArray;
private ClassMetadata() {
}
public ClassMetadata(int serviceId, Class<T> clazz) {
this();
this.serviceId = serviceId;
this.clazz = clazz;
}
#SuppressWarnings("unchecked")
public Class<T> getClazz() {
return clazz;
}
// getters and setters
}
Argument is a class that responsible from conveying class argument to a function:
public class Argument<T> {
private ClassMetadata<T> classMetadata;
private T sample;
public Argument(ClassMetadata<T> classMetadata, T sample) {
super();
this.classMetadata = classMetadata;
this.sample = sample;
}
// getters and setters
#SuppressWarnings({ "rawtypes", "unchecked" })
public boolean isAssignableFrom (Class classInstance) {
if (classInstance == null || this.classMetadata == null)
return false;
Class localClassValue = this.classMetadata.getClazz();
if (localClassValue == null)
return false;
return localClassValue.isAssignableFrom(classInstance);
}
}
I have an IRepositoryEntityFramework interface that manages database interactions of a project:
package authority.core.dataaccess.entityframework;
import java.util.List;
import javax.persistence.PersistenceException;
public interface IRepositoryEntityFramework<T> extends AutoCloseable {
void add(T value) throws PersistenceException;
void update(T value) throws PersistenceException;
void delete(T value) throws PersistenceException;
//commit
void save() throws PersistenceException ;
List<T> readList(SQL sqlClause) throws IllegalStateException, PersistenceException;
}
I have a IAuthorityDetailRepository that responsible specifically AuthorityDetail entity's database operations:
package authority.repository.conceptual;
import authority.core.dataaccess.entityframework.IRepositoryEntityFramework;
import authority.entities.concrete.AuthorityDetail;
public interface IAuthorityDetailRepository extends IRepositoryEntityFramework<AuthorityDetail> {
}
When I call the clauses below, isAssignableFrom returns false:
IAuthorityDetailRepository authorityDetailRepository = DependencyResolver.getSample().resolve(IAuthorityDetailRepository.class);
ClassMetadata<IAuthorityDetailRepository> authorityDetailRepositoryMetadata = new ClassMetadata(3,IAuthorityDetailRepository.class );
Argument<IAuthorityDetailRepository> authorityDetailRepositoryArgument = new Argument<IAuthorityDetailRepository>(authorityDetailRepositoryMetadata, authorityDetailRepository);
authorityDetailRepositoryArgument.isAssignableFrom(IRepositoryEntityFramework.class);
However, the clauses below return true;
#SuppressWarnings("rawtypes")
Class localClassValue = IAuthorityDetailRepository.class;
#SuppressWarnings("rawtypes")
Class argumentClassValue = IRepositoryEntityFramework.class;
localClassValue.isAssignableFrom( argumentClassValue);
What am I missing?
Thanks in advance.
Update-1
As Mr. Sergey Kalinichenko pointed out that Argument was missing, which implements the failing isAssignableFrom method.
As java.lang.Class#isAssignableFrom JavaDoc says:
Determines if the class or interface represented by this Class object is either the same as, or is a superclass or superinterface of, the class or interface represented by the specified Class parameter. It returns true if so; otherwise it returns false.
So, it returns true when called next way:
Base.class.isAssignableFrom(Child.class); // true
In your case, you're calling
IAuthorityDetailRepository.class.isAssignableFrom(IRepositoryEntityFramework.class)
Since IAuthorityDetailRepository is a child of IRepositoryEntityFramework, method returns false. If you intended different behaviour, just swap localClassValue and classInstance.
return classInstance.isAssignableFrom(localClassValue);
Related
What are the pros/cons of using the abstract class constructor vs. an abstract method for passing final data to an abstract class?
Pass via constructor:
public abstract class MyAbstractClass<T> {
private final String type;
private final Function<String, T> factoryFn;
protected MyAbstractClass(String type, Function<String, T> factoryFn) {
this.type = type;
this.factoryFn = factoryFn;
}
public T doSomething(String value) { ... }
}
Pass via abstract method:
public abstract class MyAbstractClass<T> {
abstract String getType();
abstract T getFactoryFn(String value);
public T doSomething(String value) { ... }
}
I'm aware that the abstract methods can potentially be misused, because it doesn't enforce to always return the same value.
But apart from that, is it just a matter of personal preference, or are there any real (dis)advantages for using one over the other?
I hope I am understanding your question correctly..
Usually, when a property of a class is always held in a field, it is more concise to use an abstract constructor. For example, consider the two following scenarios....
// Scenario 1:
abstract class AClass {
final int field;
public AClass(int f) {
field = f;
}
public int getField() {
return field;
}
}
class Class1 extends AClass {
public Class1(int f) {
super(f);
}
// Class Unique Code...
}
class Class2 extends AClass {
public Class2(int f) {
super(f);
}
// Class Unique Code...
}
// Scenario 2:
abstract class AClass {
public abstract int getField();
}
class Class1 extends AClass {
final int field;
public Class1(int f) {
field = f;
}
#Override
public int getField() {
return field;
}
// Class Unique Code...
}
class Class2 extends AClass {
final int field;
public Class2(int f) {
field = f;
}
#Override
public int getField() {
return field;
}
// Class Unique Code...
}
Scenario 1 is shorter since the getter logic for field only needs to be specified once. Whereas in scenario 2, the getter logic must be overridden by both subclasses. I find scenario 2 to be redundant... why write the same code twice when you can use java inheritance to your advantage.
As a final note, I usually don't hold functions in fields unless totally necessary. Whenever you have a function in a field, it's usually a sign that an abstract function can be applied.
Here is your original code with my advice applied...
public abstract class MyAbstractClass<T> {
private final String type;
protected MyAbstractClass(String t) {
type = t;
}
protected abstract T applyFactoryFunction(String value);
public T doSomething(String value) { ... }
}
Hope this helped!
I'm using an external library that provides tightly related classes (generated from some template), but unfortunately without a shared interface, e.g.
public class A {
public UUID id();
public Long version();
public String foo();
public String bar();
}
public class B {
public UUID id();
public Long version();
public String foo();
public String bar();
}
public class C {
public UUID id();
public Long version();
public String foo();
public String bar();
}
// ... and more: D, E, F, etc.
Given I have no influence over the external library, what's the idiomatic way to write logic common to a group of classes that share the same method signatures (at least, for the methods being used by the common logic)?
Currently I do one of three things, on a case-by-case basis:
I write helper methods that take the primitive results from each object, e.g.
private static void myHelper(UUID id, Long version, String foo, String bar) {
...
}
This way I can "unpack" an object regardless of its type:
myHelper(whatever.id(), whatever.version(), whatever.foo(), whatever.bar());
But that can get very wordy, especially when I need to work with many members.
In the scenario where I'm only working with getters (i.e. only need to access current values of the objects), I've found a way to use mapping libraries like Dozer or ModelMapper to map A or B or C to my own common class, e.g.
public class CommonABC {
UUID id;
Long version;
String foo;
String bar;
}
By playing with configuration, you can get these libraries to map all members, whether method or field, public or private, to your class, e.g.
modelMapper.getConfiguration()
.setFieldMatchingEnabled(true)
.setFieldAccessLevel(Configuration.AccessLevel.PRIVATE);
But this was kind of a "broadsword" approach, a hack that IMO isn't clearly justified merely to factor out duplicate code.
Finally, in certain other scenarios it was most succinct to simply do
private static void myHelper(Object extLibEntity) {
if (extLibEntity instanceof A) {
...
} else if (extLibEntity instanceof B) {
...
} else if (extLibEntity instanceof C) {
...
} else {
throw new RuntimeException(...);
}
}
It's obvious why this is bad.
In enterprise situations where you have to live with a library that is this way, what would you do?
I'm leaning toward writing a very explicit, if verbose, mapper (not using a generic mapper library) that translates these entities from the start. But, I wonder if there's a better way. (Like, is there a way to "cast" an object as implementing a new interface, in runtime?)
An option that is (under the hood) likely similar to the second approach, but comparatively lean and flexible, is to use Dynamic Proxy Classes. With only a few lines of code, you can let any object "appear" to implement a certain interface, as long as it has the required methods. The following is an MCVE that shows the basic approach:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.UUID;
public class DelegatingProxyExample {
public static void main(String[] args) {
A a = new A();
B b = new B();
C c = new C();
CommonInterface commonA = wrap(a);
CommonInterface commonB = wrap(b);
CommonInterface commonC = wrap(c);
use(commonA);
use(commonB);
use(commonC);
}
private static void use(CommonInterface commonInterface) {
System.out.println(commonInterface.id());
System.out.println(commonInterface.version());
System.out.println(commonInterface.foo());
System.out.println(commonInterface.bar());
}
private static CommonInterface wrap(Object object) {
CommonInterface commonInterface = (CommonInterface) Proxy.newProxyInstance(
CommonInterface.class.getClassLoader(),
new Class[] { CommonInterface.class }, new Delegator(object));
return commonInterface;
}
}
// Partially based on the example from
// https://docs.oracle.com/javase/8/docs/technotes/guides/reflection/proxy.html
class Delegator implements InvocationHandler {
private static Method hashCodeMethod;
private static Method equalsMethod;
private static Method toStringMethod;
static {
try {
hashCodeMethod = Object.class.getMethod("hashCode", (Class<?>[]) null);
equalsMethod = Object.class.getMethod("equals", new Class[] { Object.class });
toStringMethod = Object.class.getMethod("toString", (Class<?>[]) null);
} catch (NoSuchMethodException e) {
throw new NoSuchMethodError(e.getMessage());
}
}
private Object delegate;
public Delegator(Object delegate) {
this.delegate = delegate;
}
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
Class<?> declaringClass = m.getDeclaringClass();
if (declaringClass == Object.class) {
if (m.equals(hashCodeMethod)) {
return proxyHashCode(proxy);
} else if (m.equals(equalsMethod)) {
return proxyEquals(proxy, args[0]);
} else if (m.equals(toStringMethod)) {
return proxyToString(proxy);
} else {
throw new InternalError("unexpected Object method dispatched: " + m);
}
} else {
// TODO Here, the magic happens. Add some sensible error checks here!
Method delegateMethod = delegate.getClass().getDeclaredMethod(
m.getName(), m.getParameterTypes());
return delegateMethod.invoke(delegate, args);
}
}
protected Integer proxyHashCode(Object proxy) {
return new Integer(System.identityHashCode(proxy));
}
protected Boolean proxyEquals(Object proxy, Object other) {
return (proxy == other ? Boolean.TRUE : Boolean.FALSE);
}
protected String proxyToString(Object proxy) {
return proxy.getClass().getName() + '#' + Integer.toHexString(proxy.hashCode());
}
}
interface CommonInterface {
UUID id();
Long version();
String foo();
String bar();
}
class A {
public UUID id() {
return UUID.randomUUID();
}
public Long version() {
return 1L;
}
public String foo() {
return "fooA";
}
public String bar() {
return "barA";
}
}
class B {
public UUID id() {
return UUID.randomUUID();
}
public Long version() {
return 2L;
}
public String foo() {
return "fooB";
}
public String bar() {
return "barB";
}
}
class C {
public UUID id() {
return UUID.randomUUID();
}
public Long version() {
return 3L;
}
public String foo() {
return "fooC";
}
public String bar() {
return "barC";
}
}
Of course, this uses reflection internally, and should only be used when you know what you're doing. Particularly, you should add some sensible error checking, at the place that is marked with TODO: There, the method of the interface is looked up in the given delegate object.
The only technique not tried:
package aplus;
public interface Common {
...
}
public class A extends original.A implements Common {
}
public class B extends original.B implements Common {
}
I have this compilation problem:
Here is the class in question:
package huru.entity;
import io.vertx.core.json.JsonObject;
import java.util.Date;
public class BaseEntity <T extends BaseModel> extends JsonObject {
private T model;
public BaseEntity(T m){
this.model = m;
}
public void setUpdateInfo(String user){
this.model.updatedBy = user;
this.model.updatedAt = new Date();
}
public JsonObject toJsonObject(){
return JsonObject.mapFrom(this.model);
}
public T getEntityType (){
return this.model.getClass(); // doesn't compile
}
}
I also tried using
public T getEntityType (){
return T; // doesn't compile
}
but that clearly doesn't work either. Anybody know how I can return the class instance of that generic type?
I also tried this:
public Class<T> getEntityType (){
return this.model.getClass();
}
and I get:
and then I tried this:
public Class<? extends T> getEntityType (){
return this.model.getClass();
}
and I have:
You appear to be confused. You're returning the class that represents T, not a T.
Let's replace T with String and show why what you're doing makes no sense:
private String model;
public String getEntityType() {
return model.getClass();
// Of course this does not work; model.getClass() is not a string!
}
public String getEntityType() {
return String;
// This doesn't even compile.
}
To try to explain, this:
public T getEntityType() {
....
}
requires you to return an actual instance of whatever T is. Not whatever type T is representing. Just like 'String' means you should return an actual instance of String, not the concept of String, the type.
Perhaps you meant to do this:
public T getEntityType() {
return model;
}
or more likely, given that you named this method 'getEntityType', what you mean is this:
public Class<? extends T> getEntityType() {
return model.getClass();
}
Yes, ? extends T, because model is a T, or any subtype of T.
What about the following code. I think it works.
public Class<? extends BaseModel> getEntityType (){
return model.getClass();
}
class Foo<T> {
final Class<T> typeParameterClass;
public Foo(Class<T> typeParameterClass) {
this.typeParameterClass = typeParameterClass;
}
public void bar() {
// you can access the typeParameterClass here and do whatever you like
}
}
Part of the problem is that getClass is defined in Object to give you a Class< ? > with a wildcard as the generic parameter. If you want to return Class< ? extends T > you will need to cast to that:
return (Class< ? extends T >) (model.getClass());
I need to create immutable copy of an object in runtime with Java. I made use of org.springframework.cglib.beans.ImmutableBean, which can create immutable copy of an object using CGLIB.
But the problem is that it provides "first-level" immutability: it disallows change of an input object's properties, but it allows to change inner objects (e.g. get collection and add an element to it or get inner object and modify it's parameters etc.)
So the question is: what's the correct way of creating deep (recursive) immutable copy of an object so that one can't change inner objects also (at any level of nesting)?
You may traverse the object tree and use CGLIB to make each object immutable by using interceptor which skips required methods. The tough part though is to determine all methods which modify the object's state - for each object in the tree.
package ut.test;
import static org.junit.Assert.assertEquals;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import com.google.common.collect.Lists;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class MyTest {
public static class Inner {
private String data = "hello";
public Inner() {}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
#Override
public String toString() {
return data;
}
}
public static class Outer {
private List<Inner> list = Lists.newArrayList(new Inner());
public Outer() {}
public List<Inner> getList() {
return list;
}
public void setList(List<Inner> list) {
this.list = list;
}
}
public static class GetOnlyDelegatingMethodInterceptor implements MethodInterceptor {
private Object delegate;
public GetOnlyDelegatingMethodInterceptor(Object delegate) {
this.delegate = delegate;
}
#Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
if (method.getName().startsWith("get")) {
return makeImmutable(proxy.invoke(delegate, args));
}
if (method.getName().equals("toString")) {
return proxy.invoke(delegate, args);
}
if (method.getDeclaringClass().equals(Object.class)) {
return proxy.invoke(delegate, args);
}
// you may check for other methods here
// skip all others
return null;
}
}
private static Object makeImmutable(Object obj) {
if (obj == null) {
return obj;
}
Enhancer e = new Enhancer();
e.setSuperclass(obj.getClass());
e.setCallback(new GetOnlyDelegatingMethodInterceptor(obj));
return e.create();
}
#Test
public void testImmutable() {
Outer outerImmutable = (Outer) makeImmutable(new Outer());
// this is initial state
assertEquals(outerImmutable.getList().toString(), "[hello]");
// trying to set empty list
outerImmutable.setList(new ArrayList<>());
// but it's still the same
assertEquals(outerImmutable.getList().toString(), "[hello]");
// going deeper
outerImmutable.getList().get(0).setData("bye!");
// but still no changes
assertEquals(outerImmutable.getList().toString(), "[hello]");
}
}
You can use ImmutableProxy of the reflection-util library.
Example:
public class Inner
{
private String data = "hello";
// getters and setters
}
public class Outer
{
private List<Inner> list = Arrays.asList(new Inner());
// getters and setters
}
Outer outerImmutable = ImmutableProxy.create(new Outer());
Inner firstElement = outerImmutable.getList().get(0)
// this is initial state
assertThat(firstElement.getData()).isEqualTo("hello");
// throws UnsupportedOperationException
outerImmutable.setList(…);
// throws UnsupportedOperationException
firstElement.setData("bye!");
I have an third-party RPC-API that provides an interface similar to that of java.sql.ResultSet (for reading values) and java.sql.PreparedStatement (for writing values). Assume it looks something like this:
public interface RemoteDeviceProxy {
public void setBoolean(Boolean value);
public void setInteger(Integer value);
// ...
public Boolean getBoolean();
public Integer getInteger();
// ...
}
I want to write a wrapper for this API that uses generics to create instances of specific types:
public class <T> RemoteVariable {
private final RemoteDeviceProxy wrappedDevice;
public RemoteVariable(RemoteDeviceProxy wrappedDevice) {
this.wrappedDevice = wrappedDevice;
}
public T get() {
// should call wrappedDevice.getBoolean() if T is Boolean, etc.
// how to implement?
}
public void set(T newValue) {
// should call wrappedDevice.setBoolean(newValue) if T is Boolean, etc.
// implement using instanceof
}
}
How can I implement the getter in my generic wrapper? I have found this answer which explains a similar scenario in depth, but I am not able to transfer this to my problem. Specifically, when I write this:
public T get() {
Type[] actualTypeArguments = ((ParameterizedType) getClass())
.getActualTypeArguments();
}
I get a compiler error saying I cannot cast to ParameterizedType, and I do not understand why. Can anyone explain how to achieve this?
Here is one way:
public class <T> RemoteVariable {
private final RemoteDeviceProxy wrappedDevice;
private final Class<T> clazz;
public RemoteVariable(RemoteDeviceProxy wrappedDevice, Class<T> clazz) {
this.wrappedDevice = wrappedDevice;
this.clazz = clazz;
}
public T get() {
if(clazz == Boolean.class){return clazz.cast(wrappedDevice.getBoolean());}
else if(clazz == Integer.class){return clazz.cast(wrappedDevice.getInteger());}
// ...
}
// ...
}
I thought over this quite a while and finally came up with a different approach:
First I added a getter to you RemoteVariable class:
protected RemoteDeviceProxy getWrappedProxy() {
return wrappedProxy;
}
Second I created a builder interface that will be used by a factory later:
public interface RemoteVariableBuilder {
public <T> RemoteVariable<T> buildNewVariable(RemoteDeviceProxy wrappedProxy);
}
Then I created non generic sub classes for Boolean...
public class RemoteBooleanVariable extends RemoteVariable<Boolean> implements RemoteVariableBuilder {
public RemoteBooleanVariable(RemoteDeviceProxy wrappedProxy) {
super(wrappedProxy);
}
#SuppressWarnings("unchecked")
#Override
public <T> RemoteVariable<T> buildNewVariable(RemoteDeviceProxy wrappedProxy) {
return (RemoteVariable<T>) new RemoteBooleanVariable(wrappedProxy);
}
#Override
public Boolean get() {
return getWrappedProxy().getBoolean();
}
#Override
public void set(Boolean value) {
getWrappedProxy().setBoolean(value);
}
}
... and Integer ...
public class RemoteIntegerBuilder extends RemoteVariable<Integer> implements RemoteVariableBuilder {
public RemoteIntegerBuilder(RemoteDeviceProxy wrappedProxy) {
super(wrappedProxy);
}
#SuppressWarnings("unchecked")
#Override
public <T> RemoteVariable<T> buildNewVariable(RemoteDeviceProxy wrappedProxy) {
return (RemoteVariable<T>) new RemoteIntegerBuilder(wrappedProxy);
}
#Override
public Integer get() {
return getWrappedProxy().getInteger();
}
#Override
public void set(Integer value) {
getWrappedProxy().setInteger(value);
}
}
actually eclipse created most of the code once it knew base class and interface.
The final step was to create a factory
public class RemoteVariableFactory {
private static final Map<String, RemoteVariableBuilder> BUILDERS = new HashMap<>();
static {
BUILDERS.put(Boolean.class.getName(), new RemoteBooleanVariable(null));
BUILDERS.put(Integer.class.getName(), new RemoteIntegerBuilder(null));
// add more builders here
}
public static <T> RemoteVariable<T> getRemoteVariable(RemoteDeviceProxy wrappedProxy, Class<T> typeClass) {
RemoteVariableBuilder remoteVariableBuilder = BUILDERS.get(typeClass.getName());
if (remoteVariableBuilder == null) {
return null; // or throw an exception whichever is better in your case
}
return remoteVariableBuilder.buildNewVariable(wrappedProxy);
}
}
Now we are ready to create new RemoteVariables...
RemoteVariable<Boolean> var1 = RemoteVariableFactory.getRemoteVariable(new RemoteDevice(), Boolean.class);
RemoteVariable<Integer> var2 = RemoteVariableFactory.getRemoteVariable(new RemoteDevice(), Integer.class);
To conclude this let's do a quick comparison to the answer of Eng.Fouad:
Disadvantage:
you need to create a new class for every datatype you provide
Advantage:
you only have to add one line to the static block of the factory and not two new if blocks to the getter and setter in RemoteVariable
get and set do not have to work through the if-else-blocks every time