How to Pass Interface Object to a Method - java

I have a main class as shown below. I want to Pass interface object to another method from Main method. I am Passing it as shown in my Main class below. But I am getting error "; expected". Can some one please help me?
This is my Main Class :
package com.armus.web.server;
import com.armus.common.dtflow.DfService;
public class TriggerAgain
{
public static void main(String[] args){
Long i= 97944605L;
DMSerImpl rdf = new DMSerImpl();
try {
/*********** Section start....Getting Problem In this section...How Can I Pass interface object to a method setDfService*********/
#Override
rdf.setDfService(new DfService()
{
Dfsessn dfsessn=getDfsessnById(i)
{
System.out.println("In main class...In interface method="+i);
}
})
/*************************************************Section End*******************************************************************/
com.armus.dto.Jinfo a=rdf.Trigger(i);
}
catch( Throwable e){
System.out.println("In exception = "+e+" "+i);
e.printStackTrace();
return; // Always must return something
}
}
}
This is my another class to which I want to Pass interface Object to "setDfService" Method.
package com.armus.web.server;
import com.armus.common.dtflow.DfService;
import com.armus.common.dto.Dfsessn;
import com.armus.foundation.client.exception.ServiceException;
import com.armus.dto.Jinfo;
public class DMSerImpl
extends Remoteservletsup
implements DMserv, DMAjxSer
{
private DfService dtflowser;
public void setDfService(DfService dtflowser)
{
this.dtflowser = dtflowser;
}
private Dfsessn getDfsessn(long sessionId)
throws ServiceException
{
try
{
dfSession = this.dtflowser.getDfsessnById(Long.valueOf(sessionId));
}
catch (ServerException e)
{
Dfsessn dfSession;
LOG.error(e.getMessage(), e);
throw new ServiceException(e.getMessage());
}
return dfSession;
}
public com.armus.dto.Jinfo Trigger(long sessionId)
throws ServiceException
{
Dfsessn dfSession = getDfsessn(sessionId);
//some code
}
}
Below is My Interface :
package com.armus.common.dtflow;
import com.armus.common.dto.Dfsessn;
import com.armus.common.exception.ServerException;
public abstract interface DfService
{
public abstract Dfsessn getDfsessnById(Long paramLong)
throws ServerException;
}
Thank you in Advance !!! :)

This is an example of creating an instance of an anonymous class
rdf.setDfService(new DfService() {
#Override
public Dfsessn getDfsessnById(Long paramLong) {
....
}});

You are:
Putting the #Override in the wrong place;
not declaring the method override properly; and
missing a closing semicolon:
rdf.setDfService(new DfService()
{
#Override
public Dfsessn getDfsessnById(Long i)
{
System.out.println("In main class...In interface method="+i);
}
});

#Override
rdf.setDfService(new DfService()
{
Dfsessn dfsessn=getDfsessnById(i)
{
System.out.println("In main class...In interface method="+i);
}
})
Above what you are trying to do is creating an anonymous class instance implementing the DfService interface but you are not doing it correctly(syntax wise).
Read about anonymous inner classes here https://www.geeksforgeeks.org/anonymous-inner-class-java/
Also, DfService is a functional interface(single method interface) so you can also use a lamda here. Something like this.
rdf.setDfService(paramLong -> System.out.println("In main class...In interface method="+i));
Take a look at this for more info https://javarevisited.blogspot.com/2015/01/how-to-use-lambda-expression-in-place-anonymous-class-java8.html

Related

Can't invoke a method obtained through reflection

I am getting the error
Cannot invoke "Object.getClass()" because "obj" is null
on the line
m.invoke(null);
Here are the classes:
package device;
public class Conveyor {
private String ID;
public Conveyor(String ID) {this.ID = ID;}
public void Start() {
}
public void Stop() {
}
}
package main;
import java.lang.reflect.Method;
import device.Conveyor;
public class Main {
public static void main(String args[]) {
Conveyor myConveyor = new Conveyor("C1");
Class<Conveyor> conveyorClass = (Class<Conveyor>) myConveyor.getClass();
for (Method m : conveyorClass.getMethods()) {
System.out.println(m.getName());
if (m.getName().equals("Start")) {
try {
m.invoke(null);
} catch (Exception ex) {
System.err.println(ex.getLocalizedMessage());
}
}
}
}
}
Acording to the docs, the invoke method receive the reference of the object that will call the method. So you need to change the code to be:
m.invoke(myConveyor);
See the docs https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Method.html#invoke-java.lang.Object-java.lang.Object...-
Per #markspace , I edited the invoke to add the invoking object:
m.invoke(myConveyor);

Create object in function based on Class argument

I want to define a function that creates different type objects that share the same base class. I'd like to pass in the object type and have the function creating the object and then modifying its attributes. The problem is that the main class from which all these objects are created, does not have the object's attributes so the code fails to compile.
Example:
public void new_generic_report(Class report_class, String report_name) {
Report new_report = this.reportManager.createReport(report_class);
new_report.set_name(report_name);
}
Calling new_generic_report(GreenReport.class, "green_report"); fails because new_report is of the class Report instead of GreenReport so it does not have the .set_name method.
I know I could implement the .set_name method (and other common methods) in the main Report class but I am writing code to interface with an API that I cannot modify.
If you are sure that createReport returns an instance of the correct class you can just do a cast:
((SpecialClass)new_report).set_name(report_name);
An alternative is to use reflection:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test {
static class Base {};
static class Child extends Base {
public void setName(final String name) {
System.out.println("setName("+name+")");
}
}
public static void main(String[] args) {
new Test().new_generic_report(Child.class, "Testname");
}
public void new_generic_report(final Class clazz, final String name) {
Base base = createBase(clazz);
try {
Method m = clazz.getMethod("setName", String.class);
m.invoke(base, name);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
private Base createBase(Class report_class) {
return new Child();
}
}
Of course this only works, if the returned instance implements the method.
Create a parent class for your report for instance :
public abstract class NamedReport extends Report
{
public abstract void setName(String name);
}
class GreenReport extends NamedReport {
#Override
public void setName(String name) {
}
}
Then simply cast your class in your method :
public void new_generic_report(Class report_class, String report_name) {
Report new_report = this.reportManager.createReport(report_class);
if (new_report instanceof NamedReport)
{
((NamedReport)new_report).set_name(report_name);
}
}

Dynamically invoke a method from a varying class

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

How to call instance of variety of classes in java

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();
}
}
}

Trouble with constructor in the Processing Java environment

I am new to Java and working in the Processing environment. I want to create a class that has a few objects in it, but I am getting an error when I try to construct those classes' object.
The bzaVertex is supposed to be an object within the bza object, but when I seemingly try to construct it, Processing says "The constructor sketch.BzaVertext(int) is undefined." I don't understand how Bza is getting its constructor called properly, but not the child object -- I seem to be calling them the same way?
I have this code all in the main class. I'm using Processing 2.0b7. What am I doing wrong?
Bza bza;
void setup() {
bza = new Bza();
}
public class BzaVertex {
public void BzaVertex(int d) {
}
}
public class Bza {
BzaVertex v1;
public void Bza() {
v1 = new BzaVertex(4);
}
}
constructors do not have a return type so you need to to remove the void from both of them
class BzaVertex {
public BzaVertex(int d) {
}
}
class Bza {
BzaVertex v1;
public Bza() {
v1 = new BzaVertex(4);
}
}
public class Main
{
public static void main(String[] args)
{
Bza bza;
bza = new Bza();
}
}
that should solve the error

Categories

Resources