This is my test code:
Activity activityMock = Mockito.mock(TestActivity.class);
doAnswer(new Answer() {
#Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
Object[] args = invocationOnMock.getArguments(); // ->>>> args contains one Foo instance called "foo"
return invocationOnMock;
}
}).when(activityMock).runOnUiThread(any(Runnable.class));
runDialogOnUiThread(activityMock, new Foo());
To the following production code:
public static void runDialogOnUIThread(final Activity activity, final Foo foo) {
activity.runOnUiThread(new Runnable() {
#Override public void run() {
doSmth();
}
});
}
See my comment in the test code. I expect invocationOnMock.getArguments() to return the Runnable instance, but it is returning the Foo instance (Which makes absolutely no sense to me)?
I thought
doAnswer(new Answer(){..}).when(b).bMethod(any(C.class))
intercepts when bMethod() is called anywhere on b and it will pass the instance of C.class to the doAnswer() to make it available in the "new Answer().."-Callback..
How can I access the anonymous Runnable instance, which is created in the production code?
I'm guessing that your anonymous Runnable instance is defined in Foo, right?
Here's some code I wrote to try to reproduce your issue:
public class MockitoTest {
#Test
public void test() {
final Activity activityMock = Mockito.mock(TestActivity.class);
doAnswer(new Answer() {
#Override
public Object answer(final InvocationOnMock invocationOnMock) throws Throwable {
final Object[] args = invocationOnMock.getArguments();
System.out.println("Is argument a Runnable? " + (args[0] instanceof Runnable));
System.out.println("What is the argument toString()? " + args[0].toString());
return invocationOnMock;
}
}).when(activityMock).runOnUiThread(any(Runnable.class));
runDialogOnUIThread(activityMock);
}
public void runDialogOnUIThread(final Activity activity) {
final Runnable r = new Runnable() {
#Override public void run() {
System.out.println("***");
}};
activity.runOnUiThread(r);
}
public static interface Activity {
void runOnUiThread(Runnable r);
}
public static class TestActivity implements Activity {
#Override
public void runOnUiThread(final Runnable r) { r.run(); }
}
}
Pretty much the same thing, but it is trimmed down to illustrate where I think you are getting confused.
The output is:
Is argument a Runnable? true
What is the argument toString()? stackoverflow.MockitoTest$2#6b143ee9
Note that the second output contains MockitoTest for the toString() output and nothing about it being a Runnable. That's because the toString() method is not being explicitly defined in the anonymous Runnable.
Let's change the Runnable as follows:
final Runnable r = new Runnable() {
#Override public void run() {
System.out.println("***");
}
#Override public String toString() {
return "ANON RUNNABLE";
}
};
Then the output is:
Is argument a Runnable? true
What is the argument toString()? ANON RUNNABLE
What I suspect you were getting tripped up on is that the toString() output looked like the same class name as the class that the anonymous Runnable was created in.
Related
Here is the best way I could summarise my situation:
Class1 makes new Thread(new Class2)
Is there a way from inside objects 2 code I can access non-static public methods from object 1?
Not sure if I have explained myself enough but I can answer any questions that could help describe it better
Edit: To elaborate Class1 is a multithreaded server and Class2 is the WorkerClass and i want to access Class1.stop() to stop the server from inside the workerClass
There are at least 3 ways to do this:
(1) Use an anonymous inner class:
public class Class1 {
public void foo() {}
public void bar() {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
foo();
}
});
}
}
(2) Use a named inner class:
public class Class1 {
public void foo() {}
public void bar() {
Thread t = new Thread(new MyRunnable());
}
private class MyRunnable implements Runnable {
#Override
public void run() {
foo();
}
}
}
(3) Pass this to the constructor of another top-level class:
public class Class1 {
public void foo() {}
public void bar() {
Thread t = new Thread(new MyRunnable(this));
}
}
class MyRunnable implements Runnable {
private Class1 class1;
public MyRunnable(Class1 class1) {
this.class1 = class1;
}
#Override
public void run() {
class1.foo();
}
}
I have created interface with one method:
public interface ResultCallback {
void onResult(String message);
}
And I have object with method that has interface as parameter:
public class Command() {
public void methodWithCallback(int param1, String param2, ResultCallback callback) {
// There are some calculations
callback.onResult(param2);
}
}
Then In my Main Java file I write this:
public class Main() {
public static void main(String[] args) {
Command c = new Command();
c.methodWithCallback(int 0, "SOME STRING", new ResultCallback() {
#Override
public void onResult(String str) {
// work with str
outsideMethod(str);
}
});
}
public void outsideMethod(String str) {
// some code
}
}
Does this code can be considered as async? And is it safe to call outsideMethod to handle params?
As said, it is not async. For the call to be async the method should execute on another thread.
You can't call outsideMethod since it's called from a static method. You need an instance of main to be able to call outsideMethod. If it is safe or not depends on what the code is doing.
One way to make it async is the following:
public class Command {
private ExecutorService iExecutor;
public Command(ExecutorService executor) {
iExecutor = executor;
}
public void methodWithCallback(final int param1, final String param2, final ResultCallback callback) {
iExecutor.execute(new Runnable() {
#Override
public void run() {
// There are some calculations
callback.onResult(param2);
}
});
}
}
You have to know what you're doing if using threads. Things have to be thread safe etc depending on how you are doing stuff. To run Command on a single thread create a single thread Executor and pass same Executor to all Commmand, like so:
ExecutorService executor = Executors.newSingleThreadExecutor();
Command command1 = new Command(executor);
Command command2 = new Command(executor);
I've got a problem as follows: I've got the next class:
Public class foo{
Thread runningThread = null;
...
public static void start() {
runningThread = new RunningThreadImpl();
runningThread.start();
runningThread.join();
}
public static void stop() {
this.runningThread.stop();
}
}
And:
Public class runningThreadImpl implements Runnable {
...
public void run() {
while (shouldRun()){
sleep(... A long long time);
}
}
public void stop() {
shouldRun = false;
}
I've got a class using foo, And now i want it to stop. The above code defined inside a given jar, Which means i cannot edit it. But i thought about using Reflection in order to interrupt the Thread and "Wake" him up so i won't have to wait.
So far i've gotten this far:
Field field = foo.getInstance().getClass().getDeclaredField("runningThread");
field.setAccessible(true);
But i don't now what to do now. How can i use the Field in order to interrupt a thread? Is it even possible?
You could create a new class called FooHelper in the same package as Foo like so:
package same.package.as.foo;
public class FooHelper {
private final Foo foo;
public FooHelper(Foo foo) {
this.foo = foo;
}
public void stop() {
this.foo.stop();
this.foo.runningThread.interrupt();
}
}
Construct a FooHelper passing it the instance of Foo, and call the FooHelper's stop() method.
I am reading Java 8 book, and it comes with a sample I reproduce:
#FunctionalInterface
public interface Action {
public void perform();
}
An Implementor:
public final class ActionImpl implements Action {
public ActionImpl() {
System.out.println("constructor[ActionIMPL]");
}
#Override
public void perform() {
System.out.println("perform method is called..");
}
}
A caller:
public final class MethodReferences {
private final Action action;
public MethodReferences(Action action) {
this.action = action;
}
public void execute() {
System.out.println("execute->called");
action.perform();
System.out.println("execute->exist");
}
public static void main(String[] args) {
MethodReferences clazz = new MethodReferences(new ActionImpl());
clazz.execute();
}
}
If this is called the following is print into the output:
constructor[ActionIMPL]
execute->called
perform method is called..
execute->exist
Everything is all right but if I use method references not perform message method is printed! Why is this, am I missing something?
If I use this code:
MethodReferences clazz = new MethodReferences(() -> new ActionImpl());
clazz.execute();
Or this code:
final MethodReferences clazz = new MethodReferences(ActionImpl::new);
This is printed:
execute->called
constructor[ActionIMPL]
execute->exist
No exception message or anything else is printed. I am using Java 8 1.8.25 64bit.
Update
For readers that are studying like me, this is the right running code.
I have created a class the caller.
Because I need to implement a empty method "perform from the Action functional interface" which I need to pass as parameter to class constructor MethodReference I reference the "constructor of the MethodReferenceCall which is a empty constructor" and I can use it.
public class MethodReferenceCall {
public MethodReferenceCall() {
System.out.println("MethodReferenceCall class constructor called");
}
public static void main(String[] args) {
MethodReferenceCall clazz = new MethodReferenceCall();
MethodReferences constructorCaller = new MethodReferences(MethodReferenceCall::new);
constructorCaller.execute();
}
}
This
MethodReferences clazz = new MethodReferences(() -> new ActionImpl());
does not use method reference, it uses a lambda expression. The functional interface is Action's
public void perform();
So
() -> new ActionImpl()
gets translated into something similar to
new Action() {
public void perform() {
new ActionImpl();
}
}
Similarly, in
MethodReferences clazz = new MethodReferences(ActionImpl::new);
the ActionImpl::new, which does use a constructor reference, is translated into something like
new Action() {
public void perform() {
new ActionImpl();
}
}
This ActionImpl::new does not invoke new ActionImpl(). It resolves to an instance of the expected type whose functional interface method is implemented as invoking that constructor.
So the situation is something like this:
private void myMethod()
{
System.out.println("Hello World"); //some code
System.out.println("Some Other Stuff");
System.out.println("Hello World"); //the same code.
}
We don't want to be repeating our code.
The technique described here works pretty well:
private void myMethod()
{
final Runnable innerMethod = new Runnable()
{
public void run()
{
System.out.println("Hello World");
}
};
innerMethod.run();
System.out.println("Some other stuff");
innerMethod.run();
}
But what if I want to pass in a parameter to that inner method?
eg.
private void myMethod()
{
final Runnable innerMethod = new Runnable()
{
public void run(int value)
{
System.out.println("Hello World" + Integer.toString(value));
}
};
innerMethod.run(1);
System.out.println("Some other stuff");
innerMethod.run(2);
}
gives me: The type new Runnable(){} must implement the inherited abstract method Runnable.run()
While
private void myMethod()
{
final Runnable innerMethod = new Runnable()
{
public void run()
{
//do nothing
}
public void run(int value)
{
System.out.println("Hello World" + Integer.toString(value));
}
};
innerMethod.run(1);
System.out.println("Some other stuff");
innerMethod.run(2);
}
gives me The method run() in the type Runnable is not applicable for the arguments (int).
Nope, that isn't a method but an anonymous object. You can create an extra method to use for the object.
Thread thread = new Thread( new Runnable()
{
int i,j;
public void init(int i, int j)
{
this.i = i;
this.j=j;
}
});
thread.init(2,3);
thread.start();
And wrap runnable in a Thread, and call start! Not run().
Because you can't call the constructor of an anonymous class, as pointed out by #HoverCraft you could extend a named class that implements Runnable.
public class SomeClass implements Runnable
{
public SomeClass(int i){ }
}
Looks like you just want inner methods. Java does't let you have them, so the Runnable hack you describe lets you sort-of declare an inner method.
But since you want more control over it, why not define your own:
interface Inner<A, B> {
public B apply(A a);
}
Then you can say:
private void myMethod(..){
final Inner<Integer, Integer> inner = new Inner<Integer, Integer>() {
public Integer apply(Integer i) {
// whatever you want
}
};
// then go:
inner.apply(1);
inner.apply(2);
}
Or use some library that provides functor objects. There should be many. Apache Commons has a Functor that you can use.