I think this should be possible but I have a scenario where I'm executing a method which returns an object.
authentication.getUserAuthentication().getPrincipal()
ref
This returns an object which at runtime is cast to my custom object, however if I want to play around with the principal, I need to cast this. I want to approach this in a generic way and extra the id from this object. I want to simply be able to call
principle.getId();
As the principle object will be a custom object of mine I can ensure that this method is always there. How can I call this in a generic way that will allow future objects to this as long as they contain the method I am calling
You could use an interface, which essentially defines a set of functionalities that a class which implements that specific interface must obey to.
This is basically done by declaraing what you want to be able to call on your custom objects, eg:
interface Idable
{
public int getId();
}
Now you can state that your custom object implements that interface, and the compile will force you to override the method, or declare the class as abstract:
class CustomObject implements Idable
{
public int getId() {
return whatever;
}
}
Now you don't need to know anything more about your custom object, knowing that implements the interface is enough:
Idable idable = (Idable)authentication.getUserAuthentication().getPrincipal();
idable.getId();
Of course this requires you to be able to interact which the returned object, otherwise you will be forced to use reflection and lose type safety:
Object obj = authentication.getUserAuthentication().getPrincipal();
try {
obj.getClass().getMethod("getId").invoke(obj);
}
Unfortunately, you can't. The return type is not Object though, it's a instance of org.springframework.security.core.Authentication.
Sut since that interface does not declare a getID() method, you have to continue to cast the return value to your own type.
Related
I am having some (philosophical?) problems with java's generics...
Consider the following
public interface ClassA<I> {}
public class Obj implements ClassA<String> {}
public interface ClassB<I, T extends ClassA<I>> {
public I getSomething();
public T getAnotherThing();
}
This compiles and works ok, if an object of ClassB is instantiated as:
ClassB<String, Obj<String>> o = new ClassB<>();
o.getSomething(); // <-- Returns String
I was wondering if there is a way to avoid instantiating a ClassB object without having to specify the String generic as well, since it's already inside ClassA. More specifically, I'd like to use it as:
public interface ClassB<T extends ClassA<I>> { // <-- Won't compile
public I getSomething();
}
ClassB<Obj> o = new ClassB<>();
o.getSomething(); // <-- Returns String from Obj declaration, which uses ClassA<String>
I know the "problem" can be easily gotten over with the first example, but I wanted to know if there's a way of reference the actual type of the generic in the implementing ClassA object without having to pass it again in ClassB's declaration, and if not, why.
Hope I was clear enough with my dilemma.
Thanks
I think the answer is "No". :)
Java doesn't provide a way to extract a type argument from a type itself, only from an argument having that type.
Eg:
class ClassB<T extends ClassA<?>> {
<I> I getSomething(ClassA<I>) { ... }
}
... works fine and could be passed an instance of T in order to extract I. But to remove the parameter from the method (which is used only to determine the type for I) you'd need a way to determine I from T itself, and there is no such way.
In general, type inference in Java is limited to establishing a relationship between parameter types and/or between parameter and return types.
The other way, then, would be to declare I and T together as part of one generic parameter, as you tried:
public interface ClassB<T extends ClassA<I>>
But then, as you noted, this is not accepted either. Java's syntax would need to be expanded in order to allow this.
I'm trying to make my code more polymorphic. Right now I have a superclass that has four different subclasses. I have a method that accepts the superclass as a type. I want to perform some generic actions before routing it to a different method to handle other actions. Here's what I am envisioning:
public void performSomething(Super object) {
//do some generic action each time to object
object.setSuperProperty();
//now route to appropriate method to perform specific action
doSpecific(object);
}
private void doSpecific(SubA object) { }
private void doSpecific(SubB object) { }
private void doSpecific(SubC object) { }
private void doSpecific(SubD object) { }
This way if I want to add more functionality -- by creating a new subclass or whatever -- then I just need to add another method with the correct subclass type. However, this is not possible since the compiler complains about not having a doSpecific(Super object) method. Instead, in performSomething(Super object) I have to do an ugly:
if(object instanceof SubA)
doSpecific((SubA)object);
else if(object instanceof SubB)
doSpecific((SubB)object);
...
Is there a better way to do this than having to perform all the instanceof checks? Is there a design pattern that I'm not thinking of? I know that I'll lose the compile-time type check safety, but just curious what other solutions could possibly exist.
edit: Forgot to mention this. performSomething and doSpecific are part of an unrelated class I'll call ClassA. I considered creating an abstract method in the Super class so that the subclass could properly implement it. The problem is that performSomething and doSpecific depend on roughly 8 different members of ClassA. So if I wanted to delegate the method to the subclass it would require a ton of parameters like subB.doSpecific(int, int, String, String, Object, int, long, blah, blah); which I'm not sure is better than the original instanceOf check. This would also create a tight coupling between ClassA and the Super/Sub classes I have, when doesn't seem right since I just need to read values from them.
I recommend the Command Pattern.
That means: Every of your subclasses implements a doSpecific() method. Then your initial method looks like this:
public void performSomething(Super object) {
//do some generic action each time to object
object.setSuperProperty();
//now route to appropriate method to perform specific action
object.doSpecific(...);
}
The compiler picks the method of the subclass automatically - no instanceOf check for you.
I just started to learn java and i found out that, to call a method of normal class we need object but for static class we do not need any object to call we can use class reference to do that. But while coding I came across some code which really confused me. The code is.
public class MyInterceptor extends AbstractInterceptor {
#Override
public String intercept(ActionInvocation actionInvocation) throws Exception {
String result = actionInvocation.invoke();
Here my doubt is in the 3rd line we have a reference actionInvocation for a class ActionInvocation and we have not used any new keyword and now check the 4th line we used actionInvocation to access the methos invoke(). How is this possible without using new keyword? I also checked that ActionInvocation is abstract interface.
The new keyword is only used to construct an object. Once it has been created, it can be passed around between methods, other classes, and other places where an object may be stored or transmitted.
You are making a method of MyInterceptor that accepts an ActionInvocation object. This object can either be passed as null, or would have been created elsewhere. You can perform a not-null check (via actionInvocation!=null) to ensure that you're indeed passed an object.
Also, you should remember that you yourself can create objects without using new in your class. There are such ways called factories, where you call a static method such as ByteBuffer.allocateDirect( and that internally uses the new keyword to create an instance of ByteBuffer.
That's perfectly fine code. The ActionInvocation instance is created elsewhere and passed to the intercept(...) method. In fact ActionInvocation actionInvocation is just a reference to an object of a class that extends or implements ActionInvocation, i.e. the actual class of that object could be a subclass/implementation of ActionInvocation.
The concept behind this is called polymorphism: an object of a certain class is also an object of its superclasses and/or might be referenced through implemented interfaces.
An example:
Suppose you have an object like this:
Integer someInt = new Integer(1);
You could pass someInt as a parameter to the following methods:
void doSomething( Integer i) { ... }
void doSomething( Number n) { ... }} //because Integer extends Number
void doSomething( Object o) { ... } //because all objects extend Object
void doSomething( Comparable c) { ...} //because Integer implements Comparable (note that I left out generics here for simplicity)
Note that you could also pass null as an object, as the others already stated, but in your case you should be safe to assume that actionInvocation is never null (this is most likely documented in the API docs).
actionInvocation is initialized(with new) in another place of the program.
You will need a little more understanding of how inheritance and interfaces work to understand this. But the overall logic here is that the method is assuming that object of type ActionInvocation is already instantiated, which might not be the case. Anyways you can look at the calling code for method intercept where an object being passed here must have been instantiated by using new.
By the way ActionInvocation is interface so any "subclass" of this interface can call this method. Have a look at the inheritance terminology to understand what that means.
public String intercept(ActionInvocation actionInvocation)
To call this method any where in your program,
you need to have a created object of type ActionInvocation, then and then only you can call that method.
Once you pass to that,The story inside is usual.
In short,
That object created before calling this method and coming here to do the stuff.
I'm developing a web-app in Java language, which is composed by a system and some modules. All of them implement the IAppIdentifier interface and I have all the module references and the system itself stored in a List into the system.
The idea is to design that in such way that every module will be able to access the system itself or another modules if they have the required interface (extended from IAppIdentifier), so they have to ask the system for them.
I have this code which works:
#Override
public IAppIdentifier moduleByClass(Class<? extends IAppIdentifier> clazz) {
List<IAppIdentifier> iApps = this.get_Iapps();
for (IAppIdentifier iApp : iApps) {
if (clazz.isAssignableFrom(iApp.getClass())) {
return iApp;
}
}
return null;
}
Basically it's checking that each class from the array is assignable from the required interface and if it is it will return that instance. However the matter is that I have to cast it when it's returned by the method.
For example I have to implement something like that to obtain system's instance:
((ISystem) this.get_Service().moduleByClass(ISystem.class))
My question is, is there any way in java to avoid doing that casting again, ergo, to ensure it will return the same type I'm passing as argument at compile time?
Change method signature to this one :
public <T extends IAppIdenfitier> T moduleByClass(Class<T> clazz)
This should work.
Even if your interface isn't generic you can still use generics in methods for they own purpose. By this code you provide generic rule that T has to be IAppIdentifier itself or has to extend it. Your method now will return object of type T and take as param class as Class<T>.
Then in your code whenever you invoke method moduleByClass you don't have to cast it, for example:
ISystem = this.get_Service().moduleByClass(ISystem.class);
Cast won't be needed here and everything will compile.
There is more info needed according to #XtremeBiker good comment. Inside moduleByClass method it's needed to cast resulting type to T. So it was:
return iApp;
But now it should be:
return clazz.cast(iApp);
Anyway it's still less annoying to make cast in on place inside method body than doing it everytime when that method is invoke.
Right now I the following:
1) A java interface.
2) A concrete java class that does not implement the aforementioned interface, but does contain a method signature matching every one of the methods defined in the interface.
Since I am unable to change the implementation of item 2, I would like to know if it is possible to make a method that accepts an instance of item 1 as an argument accept item 2 without a class cast exception.
It feels like the various weaving/coercion/AOP mechanics in Spring should make this possible, but I don't know how to do it.
Is there a way to make this happen?
Can you force a java object into implementing an interface at runtime?
Yes, using dynamic proxies or byte-code rewriting. However, to me it seems like you're looking for the Adapter pattern.
You can't make the object itself implement the interface, but you could use something like Proxy to create an object which implements the interface and uses reflection to call the appropriate member on the original object.
Of course, if it's just the one interface type and the one concrete type, you could easily write such a wrapper without using Proxy:
public class BarWrapper implements Foo
{
private final Bar bar;
public BarWrapper(Bar bar)
{
this.bar = bar;
}
public int someMethodInFoo()
{
return bar.someMethodInFoo();
}
// etc
}
This should be solvable with an adapter.
Have an other class defined that implements your interface and delegates to the real object:
class YourAdapter implements YourInterface {
private final YourClass realObject;
public YourAdapter(YourClass realObject) {
this.realObject = realObject;
}
#Override
public methodFromInterface() {
// you said the class has the same method signatures although it doesn't
// implement the interface, so this should work fine:
realObject.methodFromInterface();
}
// .......
}
Now, given a method that expects YourInterface and an object of type YourClass:
void someMethod(YourInterface param) {}
void test() {
YourClass object = getFromSomewhere();
someMethod( YourAdapter(object) );
}
You can probably do what you want with Javassist, either by modifying the class's bytecode or creating a wrapper/proxy class.
Basically there are two ways:
a) write a decorator around your Object that implements the interface and delegates to your object (this can be done either by using proxies or by writing a simple adapter class)
b) change the byte code. Spring AOP is not powerful enough to do that, but the AspectJ compiler is. It's a one-liner:
declare parents: YourClass implements YourInterface;
Since you don't have access to the class source you will have to either use Load Time Weaving or weave the library jar. All of this is explained well in AspectJ in Action by Ramnivas Laddad