I'm new to Java, but I understand the basics. I know that interfaces are abstract classes and they're used for emulating multiple inheritance (kind of - I know that in Java this is not allowed). I have this code; would you explain it to me?
Here is part of a method that iterates over a list of classes:
Constructor[] c = aClass.getConstructors();
for (Constructor constructor : c) {
if (constructor.getParameterTypes().length == 0) {
AInterface action = (AInterface) constructor.newInstance();
try {
action.run(request, response);
}
}
}
Here is the interface definition used by the above code:
public interface AInterface
{
void run(HttpServletRequest request, HttpServletResponse response);
}
It uses reflection to create an instance of the class whose java.lang.Class object is stored in the aClass variable, using it's zero-argument constructor (if it has one), and then calls one of its methods (it is assumed to implement AInterface).
That code looks like it's from some web framework. Why are you looking at it? Reflection is one of the more advanced things about Java, not something that beginners usually need to deal with.
For what is calling the method run, if the method run hasn't a body? For what is good?
The class which is created (aClass) is a concrete class, not an interface, and it will implement the interface and contain the body of the run method. You need to learn more about interfaces (Google is your friend).
It's looking for a 0-argument constructor for the class AClass. There will not be more than one. :)
It then creates an instance of that class using that constructor.
It then calls the "run" method of that class with two objects.
Hope this helps.
Constructor[] c = aClass.getConstructors(); // Retrieve all the constructors
// of the class 'aClass'
for (Constructor constructor : c) { // Iterate all constructors
// Until the only default constructor is found.
if (constructor.getParameterTypes().length == 0) {
// Create a new instance of 'aClass' using the default constructor
// Hope that 'aClass' implements 'AInterface' otherwise ClassCastException ...
AInterface action = (AInterface) constructor.newInstance();
try {
// action has been cast to AInterface - so it can be used to call the run method
// defined on the AInterface interface.
action.run(request, response);
} // Oops - missing catch and/or finally. That won't compile
}
}
// Missing a bit of error handling here for the countless reflection exception
// Unless the method is declared as 'throws Exception' or similar
Example of usage:
You have a class somewhere called 'TheClass'
public class TheClass implements AInterface {
public void run(HttpServletRequest request, HttpServletResponse response) {
System.out.println("Hello from TheClass.run(...)");
// Implement the method ...
}
}
Somewhere in the application, either using Reflection or reading a Configuration file.
The application finds out that it should execute 'TheClass'.
You do not have any indication about 'TheClass' other that it should implement AInterface and it has an default constructor.
You can create the Class object using
Class aClass = Class.forName("TheClass");
and use 'aClass' in you previous code snippet (after adding the code for errorhandling). You should see in the console
Hello from TheClass.run(...)
Related
I have a method which adds Objects to an static list like this:
#PostConstruct
protected void registerToTransactionList() {
TransactionValidator.registerTransactionList(this);
}
registerTransactionList method just adds "this" to the static list, this method is in BalanceTransactionValidator class which extends TransactionValidator (owner of static list),the problem is all subclasses of BalanceTransactionValidator class are added to static list either,and if I override registerToTransactionList method in them like this:
#Override
#PostConstruct
protected void registerToTransactionList() {
}
It doesn't add subclasses but doesn't add BalanceTransactionValidator either. Can anybody help me on this? Please notice sublasses are overriding this method by default.
make the method private to block the visibility
private void registerToTransactionList() {
}
or make the method final to block it from been override
protected final void registerToTransactionList() {
}
There are two ways of achieving that:
Keep your method as it is; but then you have to actively check for the type of your objects before externally calling that method
Change your whole logic and make that method private
It won't help to make the method final as suggested in one of the comments - your problem is not that subclasses are overwriting that method; in essence, you have a design problem: you wish that subclasses should not invoke that method at all.
So, the only real option that makes sense here is "2.". You see, by having public method on a class that you want to be extended you are implicitly saying: it is perfectly fine to call that method; on any object that is instance of the base class (or child class!).
And in your case, that is not true: you actually do not want that the code behind this method runs for child classes. Then you shouldn't put that method in the list of public/protected methods of your base class!
Finally: you might want to step back and do some reading about good OO design. Class hierarchies do not fall from the sky: you willfully design them for a certain purpose. In other words: there is more to inheritance than just putting some "A extends B" on your class declaration. You have to understand each and every method on your B class; and how your child classes should deal with them!
EDIT: after some more thinking, I guess you are doing things "the wrong way", like:
class BaseClass {
public final void doRegistration() {
BaseClass toRegister = getObjectForRegistration();
if (toRegister != null) { ... register toRegister ...
}
protected BaseClass getObjectForRegistration() {
return null;
}
With that code, you could then put
protected BaseClass getObjectForRegistration() {
if (this instanceof ClassThatShouldBeRegistered) {
return this;
}
return null;
}
into that one class that wants to be registered. Probably there could be even nicer ways of doing so; but after some thinking I don't see how we could avoid the instanceof. But the above code should work; and it only requires specific code only in your base class and in that one class that wants to register something.
I have a little problem with default methods in Interface and BeanInfo Introspector.
In this example, there is interface: Interface
public static interface Interface {
default public String getLetter() {
return "A";
}
}
and two classes ClassA and ClassB:
public static class ClassA implements Interface {
}
public static class ClassB implements Interface {
public String getLetter() {
return "B";
}
}
In main method app prints PropertyDescriptors from BeanInfo:
public static String formatData(PropertyDescriptor[] pds) {
return Arrays.asList(pds).stream()
.map((pd) -> pd.getName()).collect(Collectors.joining(", "));
}
public static void main(String[] args) {
try {
System.out.println(
formatData(Introspector.getBeanInfo(ClassA.class)
.getPropertyDescriptors()));
System.out.println(
formatData(Introspector.getBeanInfo(ClassB.class)
.getPropertyDescriptors()));
} catch (IntrospectionException e) {
e.printStackTrace();
}
}
And the result is:
class
class, letter
Why default method "letter" is not visible as property in ClassA? Is it bug or feature?
I guess, Introspector does not process interface hierarchy chains, even though with Java 8 virtual extention methods (aka defenders, default methods) interfaces can have something that kinda sorta looks like property methods. Here's a rather simplistic introspector that claims it does: BeanIntrospector
Whether this can be considered a bug is somewhat of a gray area, here's why I think so.
Obviously, now a class can "inherit" from an interface a method that has all the qualities of what's oficially considered a getter/setter/mutator. But at the same time, this whole thing is against interface's purpose -- an interface can not possibly provide anything that can be considered a property, since it's stateless and behaviorless, it's only meant to describe behavior. Even defender methods are basically static unless they access real properties of a concrete implementation.
On the other hand, if we assume defenders are officially inherited (as opposed to providing default implementation which is a rather ambiguous definition), they should result in synthetic methods being created in the implementing class, and those belong to the class and are traversed as part of PropertyDescriptor lookup. Obviously this is not the way it is though, otherwise the whole thing would be working. :) It seems that defender methods are getting some kind of special treatment here.
Debugging reveals that this method is filtered out at Introspector#getPublicDeclaredMethods():
if (!method.getDeclaringClass().equals(clz)) {
result[i] = null; // ignore methods declared elsewhere
}
where clz is a fully-qualified name of the class in question.
Since ClassB has custom implementation of this method, it passes the check successfully while ClassA doesn't.
I think also that it is a bug.
You can solve this using a dedicated BeanInfo for your class, and by providing somthing like that :
/* (non-Javadoc)
* #see java.beans.SimpleBeanInfo#getAdditionalBeanInfo()
*/
#Override
public BeanInfo[] getAdditionalBeanInfo()
{
Class<?> superclass = Interface.class;
BeanInfo info = null;
try
{
info = Introspector.getBeanInfo(superclass);
}
catch (IntrospectionException e)
{
//nothing to do
}
if (info != null)
return new BeanInfo[] { info };
return null;
}
This is because you only have your method on Interface and ClassB, not on ClassA directly. However it sounds to me like a bug since I'd expect that property to showup on the list. I suspect Inrospector did not catch up with Java 8 features yet.
I really hope I am just missing something simple, but I am reading the following: http://docs.oracle.com/javase/tutorial/java/IandI/override.html .
I have two classes and one interface. Literally the "use case" shown in this Oracle documentation page. However, when I run a JUnit test - only the method in the superclass gets called and that method has the simple default that I don't want called:
The interface contains this method signature:
public interface RecordServiceInterface {
List<String> searchRecords(String id) throws ServiceException;
}
The superclass which implements the interface contains this method with a default - Eclipse IDE inserts this when it finds a missing method not implemented by the implementing class.
public class RecordService implements RecordServiceInterface {
public List<String> searchRecords(String id) throws ServiceException {
// TODO Auto-generated method stub
return null;
}
}
At runtime, only the above is called as I step through the debugger... every time.
The subclass then extends the superclass and has the real implementation that one wants to override:
public class MyRecordService extends RecordService {
#Override
public List<String> searchRecords(String id) throws ServiceException {
List<String> myList = new ArrayList<String>();
// ...
return myList;
}
}
I must be completely missing the point of #Override. During execution, it repeatedly fails to ever get into the method with the #Override annotation.
All that the #Override annotation does is make the compiler generate an error if there is no corresponding method anywhere in the class inheritance that could be overridden. So it is meant to make sure that your overridden method actually overrides something.
If your method from MyRecordService is not called, but the one from the RecordService class, then I would guess that the wrong object is instanciated. So what you have in front of you is an object of type RecordService, not of type MyRecordService.
Since you have not provided that part of the code, this is just a guess, based on the fact that your inheritance looks fine.
#Override is a compile-time annotation and is used to verify that the annotated method actually overrides something from a superclass / interface. It does not influence runtime behavior.
Post the code for your test so we can get a clearer idea of what you're trying to do.
As you can see in #Override's javadoc, the retention policy of #Override is SOURCE. In other words: it used in compile time but does not make it to the generated binary code (class file).
In particular, the SOURCE retention policy is defined as:
Annotations are to be discarded by the compiler.
#Override is effectively just a way to catch typos when attempting to override a super class' or instance's method, as well as the occasional attempt to override final methods (by design not overridable).
The act of overriding enables a fall-thru approach to overriding method when given a choice of what to call.
For example:
RecordServiceInterface service = new RecordService();
RecordService service2 = new RecordService();
With both service and service2, the implementation from RecordService will be called. Now consider:
RecordServiceInterface service3 = new MyRecordService();
RecordService service4 = new MyRecordService();
MyRecordService service5 = new MyRecordService();
With service3, service4, and service5, the implementation from MyRecordService will be called.
Overriding does not replace methods for parent types unless it is part of the chain (e.g., all three of the instances created in the last block, 3 through 5). If the instance of your Object does is not the type (MyRecordService in this case), then the method is not overridden for that instance with its behavior. service and service2 will still call RecordService's implementation.
It may be more clear with another example:
public interface Runnable {
void run();
}
public class RunnableA implements Runnable {
#Override
public void run() { System.out.println("A"); }
}
public class RunnableB extends RunnableA {
#Override
public void run() { System.out.println("B"); }
}
public class RunnableC implements Runnable {
#Override
public void run() { System.out.println("C"); }
}
You can only have an instance of any one of them, so it will only output one line per call of instance.run(). It depends on the implementation of the instance, and not what exists on the classpath.
I have a class that implements an interface. There's another class that implements this interface, too, and an instance of this second class backs my class's implementation.
For many of the methods specified by the interface, my class simply forwards them straight to the second class.
public class MyClass implements MyInterface
{
private OtherClass otherClassInstance; // Also implements MyInterface.
// ...
void foo() { otherClassInstance.foo(); }
void bar() { otherClassInstance.bar(); }
void baz() { otherClassInstance.baz(); }
// ...
}
Simply deriving my class from the second class would eliminate all of this, but it doesn't make sense because the two classes are unrelated to each other (besides implementing a common interface). They represent different things - it just so happens that a lot of my class's implementation copies that of the other class. In other words, my class is implemented atop the second class, but it is not itself a subset of the second class. As we know, inheritance is meant to express an "is-a" relationship, not to share implementation, so it's inappropriate in this case.
This portion of a talk by Joshua Bloch illustrates the situation well.
I know that Java doesn't have any language support for delegation. However, is there at least some way to clean up my class's implementation so it isn't so redundant?
An answer which is not really an answer to your actual question:
I'd say, live with the boilerplate. Let IDE generate it for you. Example: in Netbeans, add the private ArrayList field, set cursor to where you'd want the methods to appear, hit alt-insert, select "Generate Delegate Method...", click the methods you want to create a delegate for in the dialog opens, submit, go through the generated methods and make them do the right thing, you're done.
It is a bit ugly, but it is still preferable to starting to mess with reflection, when you are dealing with just one class, like it sounds. Your class is probably the kind of class, which you will complete and fully test, and then hopefully never touch again. Reflection creates runtime cost which does not go away. Suffering the auto-generated boilerplate in the source file is probably preferable in this case.
First way to use http://java.sun.com/javase/6/docs/api/java/lang/reflect/Proxy.html see tutorial http://docs.oracle.com/javase/1.4.2/docs/guide/reflection/proxy.html
Second way using AOP you can create dispatcher that intercept all invocation of specific class
For both ways you need to manage methods processing using reflection API
EDITED TO SHOW IDEA
Following code taken from tutorial above just modified a little (see youListImpl.getRealArrayList() in invoke method)
public class DebugProxy implements java.lang.reflect.InvocationHandler {
private YouListImpl youListImpl;
public static Object newInstance(Object obj) {
return java.lang.reflect.Proxy.newProxyInstance(
obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(),
new DebugProxy(obj));
}
private DebugProxy(Object obj) {
this.obj = obj;
}
public Object invoke(Object proxy, Method m, Object[] args)
throws Throwable
{
Object result;
try {
System.out.println("before method " + m.getName());
result = m.invoke(youListImpl.getRealArrayList(), args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
} catch (Exception e) {
throw new RuntimeException("unexpected invocation exception: " +
e.getMessage());
} finally {
System.out.println("after method " + m.getName());
}
return result;
}
}
I wish to initialize an array of java methods in the child class, as a class field like so
void callme() {System.out.println("hi!");}
Method[] actions = new Method[] {&callme,&callme};
and call all methods in this array at parent class like so:
for (meth:actions) {meth.invoke();}
However currently I cannot find a way to implicitly initialize the actions array, not through the constructor. The following gives me an error due to unhandled exception:
Method[] actions = new Method[] {
this.getClass().getDeclaredMethod("count")
};
As said, I cannot catch the exception when initializing this array explicitly as a field, and not in the constructor.
I'm a newbie to java reflection, so this is probably an obvious question, still I found no answer to that at google, any help would be appreciated.
Thanks
P.S.
As Scott below guessed, I "want a superclass to call a specific set of methods defined in a subclass".
Are you sure reflection is the right thing to do? Normally an interface with several anonymous classes implementing it would be better style.
You can write an initializer block to be able to catch the exception during initialization.
Why don't you use getMethod()?
[Note: code below has not been compiled but should get the idea across]
I should echo -- what are you trying to accomplish?
If you want a superclass to call a specific set of methods defined in a subclass, you can do a few things.
With reflection, I'd recommend using annotations:
1) define an annotation HeySuperclassCallMe (make sure retention is RUNTIME)
2) annotate the methods to call with HeySuperclassCallMe
#HeySuperclassCallMe public void foo...
3) in your superclass do something like
for (Method m : getClass().getMethods())
if (m.getAnnotation(HeySuperclassCallMe.class) != null)
m.invoke(...)
That's a nice reflective means to do it.
For non-reflection (which should be a bit faster, but more code):
1) define an interface that represents the calls
public interface Call {
void go();
}
2) in your superclass, define a
private List<Call> calls
protected void addCall(Call call)
3) in the subclass, use addCall:
addCall(new Call() {public void go() {foo();}} );
4) in the superclass
for (Call call : calls)
call.go();
Check out the Apache Commons - Beanutils! It's like a wrapper around all the reflection which is very easy to use. It wraps method invocation, modify attributes, lookups...
If you want to bring in dynamic to Java, you should have a look a dynamic JVM languages which can be used by simple including a .jar library! On of them is Groovy which contains the java syntax and bring in a lot of dynamic functionality (scripting, rapid-prototyping, Meta-Object-Protocol, runtime-method repacement, dynamic proxies...).
This should work as long, as your method is really declared in in the this.getClass().
If it is inherited, you should use Class.getMethod() instead.
However, instead of using function pointers, in java one would define an interface with a method one want to call, and let that interface be implemented by the target object.
Also consider using ArrayList, or other collection classes instead of arrays.
I can tell by your ampersands that you are thinking in C. We don't really use pointers to functions in java.
Generally, you would not use java reflection for this. As one of the other posters said - you would create an interface, and have objects that implemented that interface - either by directly implementing it, or with an adapter or anonymous class:
interface Callable { void callme(); }
Callable[] foo = new Callable[] {
new Callable() { public void callme() {System.out.println("foo!");}},
new Callable() { public void callme() {System.out.println("bar!");}}
};
for(Callable c: foo) {
c.callme();
}
Create a static method in your class which will return an array of declared methods and do the correct handling of exceptions.
private static Method[] declaredMethods(Class<T> clazz, String methodName) {
Method[] result = new Method[1];
try{
result[0] = clazz.getDeclaredMethod(methodName);
} catch (NoSuchMethodException nsme) {
// respond to the error
} catch (SecurityException se) {
// Respond to the error
}
return result;
}
Method[] actions = declaredMethods("count");