I want to create a menu which should be populated by arbitrary methods, which are marked by an annotation. The methods should be invoked from inside the base class. Unfortunately 'java.lang.ClassCastException' is thrown since the method.invoke function expects an object which is instance of the child class. But i only get the base class.
Here is what i tried so far :
public abstract Class BaseClass{
private void invokeSomeMethod(){
final Method[] methods= getClass().getDeclaredMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(MenuFunction.class)) {
MenuFunction menuFunction = method.getAnnotation(MenuFunction.class);
menuFunction.invoke(this); //Throws 'java.lang.ClassCastException'
}
}
}
#Retention(RetentionPolicy.RUNTIME)
#Target({ METHOD })
public #interface MenuFunction {
String Label();
}
}
public Class ChildClass extends BaseClass{
#MenuFunction(Label = "First method")
public void setHigh(){
//Arbitrary function
}
#MenuFunction(Label = "Another method")
public void setLow(){
//Do something
}
}
I guess what you want to do is this:
public abstract class BaseClass {
public void invokeSomeMethod() throws InvocationTargetException, IllegalAccessException {
final Method[] methods = getClass().getDeclaredMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(MenuFunction.class)) {
MenuFunction menuFunction = method.getAnnotation(MenuFunction.class);
method.invoke(this); //invoke method here'
}
}
}
}
public class ChildClass extends BaseClass{
#MenuFunction(Label = "hello")
public void hello() {
System.out.println("hello");
}
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
new ChildClass().invokeSomeMethod();
}
}
Result:
hello
Related
I am writing unit tests for my akka actor classes. a field is being declared in abstract parent class and instantiated inside its constructor. During test case execution of child class that field is showing null. So how to instantiate the field from the test class.
Note: I am using partial Mocking also in testNG classes.
public abstract class ParentClass extends UntypedActor {
protected RestTemplate restTemplate;
protected ObjectMapper objMapper;
public ParentClass () {
super();
restTemplate = new RestTemplate();
objMapper = new ObjectMapper();
}
}
public class ChildClass extends ParentClass{
public ChildClass () {
super();
}
public void invoke(String json) throws Exception {
BeanClass bean = objMapper.readValue(json, Bean.class);
}
public String getJsonResponse(String json){
sysout("Get");
return "response";
}
}
public class ChildClassUnitTest {
#BeforeTest
public void setUp() throws Exception{
actorMock = PowerMock.createPartialMock(ChildClass.class,"getJsonResponse");
actorMock.getJsonResponse("req");
PowerMock.expectLastCall().andReturn("resp").anyTimes();
PowerMock.replay(actorMock);
}
#Test
public void testInvokePos() throws Exception{
ResponseClass response=actorMock.invoke("req");
System.out.println(response);
}
}
I am not known to json and I can only help with java code.
Please look at code below.
And my instance fields are initialized properly. They are not null. So I don't see any problem with your code atleast with what you have posted. Need to visit your UntypedActor class.
class ClassA
{
String x;
public ClassA ()
{
x = "Java";
}
}
abstract class ParentClass extends ClassA{
protected String restTemplate;
protected Integer objMapper;
public ParentClass () {
super();
restTemplate = " Language";
objMapper = 1;
}
}
class ChildClass extends ParentClass{
public ChildClass () {
super();
}
}
class HelloWorld
{
public static void main (String args[] )
{
ChildClass cc = new ChildClass ();
System.out.println ( cc.x + cc.restTemplate + cc.objMapper );
}
}
Output for the code is as expected
Java Language1
I have a requirement where in i need to invoke method from class in a particular pattern which is obtained as input argument.
public RandomMethod(String ClassName){
//Eg For Class Name Abc , there is a method AbcProcessor which i need to invoke
ClassName.ClassNameProcessor
}
Since i am getting the argument as String , i am not able to figure out how to cast String into a form where i can call something like Abc.AbcProcessor()
I believe there is some way to do this using reflections. But i am not sure how to proceed.
By reflection you can do that, try following sample:
Class A:
public class A {
public void print(){
System.out.println("A");
}
}
Class B:
public class B {
public void print(){
System.out.println("B");
}
}
Invoking print() from A and B:
public class Test {
public static void callPrint(String className){
try {
Class clazz = Class.forName(className);
Object obj = clazz.newInstance();
clazz.getDeclaredMethod("print").invoke(obj);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) {
callPrint("test.A");
callPrint("test.B");
}
}
You need to use reflecton, indeed:
public void randomMethod(String fullyQualifiedClassName, String methodName) throws ReflectiveOperationException {
Class<?> clazz = Class.forName(fullyQualifiedClassName);
clazz.getMethod(methodName).invoke(null);
}
which would work assuming you are calling public static method with no arguments
I create a class to handle some specific job that use variety of classes on my project.
But after finish the job class must call-back specific method on the called classes.
I use interface to handle this call-back method.
How can I store the called class?
I can get the instance from constructor but I'm looking for generic way.
Your question is not clear but it may be possible that you have missed the fact that classes can implement more than one interface.
public interface DoesAJob {
public void doIt();
}
public interface Finishes {
public void finish();
}
class AThing implements DoesAJob, Finishes {
#Override
public void doIt() {
}
#Override
public void finish() {
}
}
private void doTheJob(DoesAJob thing) {
thing.doIt();
}
private void finishUp(Finishes thing) {
thing.finish();
}
public void test() {
AThing thing = new AThing();
doTheJob(thing);
finishUp(thing);
}
You can use just Java Interface, or use Java Reflection.
First the Interface
package test;
public interface MyClassInterface {
public String getName();
}
next, the Interface Implementation
package test;
public class MyClassImplementation implements MyClassInterface {
String name;
public MyClassImplementation() {
name= "Whatever";
}
public String getName() {
return name;
}
}
finally invoke the class. just Interface example:
package test;
public class MainTest {
public static void main(String[] args){
MyClassInterface myClassImplementation = new MyClassImplementation();
System.out.println(myClassImplementation.getName());
}
}
Using Reflection example:
package test;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class MainTest {
public static void main(String[] args)
throws InstantiationException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException, NoSuchMethodException, SecurityException {
//using reflection
Object otherClassImplementation=null;
try {
Class<?> cls = Class.forName("test.MyClassImplementation");
otherClassImplementation = cls.newInstance();
Method method = cls.getMethod("getName");
System.out.println(method.invoke(otherClassImplementation));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
i want to use the method of my child class dynamically!
how can i access to child method?
the parent class is :
public abstract class A{
String temp;
public abstract String getData();
public void setData(String temp){
this.temp=temp;
}
and childs class is:
public class B extends A{
#Override
public String getData() {
return "B--GetData";
}
#Override
public void setData(String temp) {
this.temp= temp+"-B";
}
public class C extends A{
#Override
public String getData() {
return "C--GetData";
}
#Override
public void setData(String temp) {
this.temp= temp+"-C";
}
}
i use this code to access my child class
String parseData(String Name){
Class<?> cls = Class.forName(Name);
cls.getMethods();
}
how can i able to call for example getData() method from class C dynamically?
thanks
public String parseData(String Name) throws Exception {
Class<?> cls = Class.forName(Name);
Method[] methods = cls.getMethods();
for (Method method : methods) {
if(method.getName().equals("setData")) {
method.invoke(cls.newInstance(), "Test");
}
}
return null;
}
Please try to use like that.
You call method like below
parseData(C.class.getName());
You can call your method like this :
methods[0].invoke(new B(), null);
you can use `method[1]` or `new C()` based on which method to call and on which object.
The below code also shows how to access private methods as well.
Example :
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
class ExitPuzzle extends MyAbstractClass {
public static void main(String... args) throws IllegalArgumentException,
IllegalAccessException, InvocationTargetException {
Class clazz = MyAbstractClass.class;
Method[] methods = clazz.getDeclaredMethods();
System.out.println(Arrays.toString(methods));
methods[0].setAccessible(true); // needed only if method is non-public
methods[0].invoke(new ExitPuzzle(), null);
}
}
abstract class MyAbstractClass {
private void myMethod() {
System.out.println("in MyAbstractClass");
}
}
Code base is littered with code like this:
BaseRecord record = // some BaseRecord
switch(record.source()) {
case FOO:
return process((FooRecord)record);
case BAR:
return process((BarRecord)record);
case QUUX:
return process((QuuxRecord)record);
.
. // ~25 more cases
.
}
and then
private SomeClass process(BarRecord record) { }
private SomeClass process(FooRecord record) { }
private SomeClass process(QuuxRecord record) { }
It makes me terribly sad. Then, every time a new class is derived from BaseRecord, we have to chase all over our code base updating these case statements and adding new process methods. This kind of logic is repeated everywhere, I think too many to add a method for each and override in the classes. How can I improve this?
First solution: good old polymorphism.
Simply add an abstract process() method to the BaseRecord class, and override it in every subclass. The code will thus become:
BaseRecord record = ...;
record.process();
If you can't add the process() method into the BaseRecord class (and its subclasses), then implement the visitor pattern. It will leave the process method outside of the BaseRecord class, but each time you add a new subclass, you'll be forced to modify the Visitor interface, and all its implementations. The compiler will thus check for you that you haven't forgotten a case somwhere in a switch.
public interface RecordVisitor<T> {
T visitFoo(FooRecord foo);
T visitBar(BarRecord foo);
...
}
public abstract class BaseRecord {
public abstract <T> T accept(RecordVisitor<T> visitor);
}
public class FooRecord extends BaseRecord {
#Override
public <T> T accept(RecordVisitor<T> visitor) {
return visitor.visitFoo(this);
}
}
public class BarRecord extends BaseRecord {
#Override
public <T> T accept(RecordVisitor<T> visitor) {
return visitor.visitBar(this);
}
}
Now you simply have to implement RecordVisitor for each block of logic described in the question:
RecordVisitor<Void> visitor = new ProcessRecordVisitor();
record.accept(visitor);
Both Visitor Pattern and Strategy pattern can be put in use here. http://en.wikipedia.org/wiki/Strategy_pattern and http://en.wikipedia.org/wiki/Visitor_pattern
I think this is instructive:
package classplay;
public class ClassPlay
{
public void say(String msg) { System.out.println(msg); }
public static void main(String[] args)
{
ClassPlay cp = new ClassPlay();
cp.go();
}
public void go()
{
A someClass = new C();
say("calling process with double dispatch");
someClass.dueProcess(this);
say("now calling process directly");
process(someClass);
}
public void process(A a)
{
say("processing A");
a.id();
}
public void process(B b)
{
say("processing B");
b.id();
}
public void process(C c)
{
say("processing C");
c.id();
}
abstract class A
{
abstract public void id(); // { System.out.println("Class A"); }
public void dueProcess(ClassPlay cp) { cp.process(this); }
}
class B extends A
{
public void id() { System.out.println("Class B"); }
public void dueProcess(ClassPlay cp) { cp.process(this); }
}
class C extends A
{
public void id() { System.out.println("class C"); }
public void dueProcess(ClassPlay cp) { cp.process(this); }
}
}