Android Studio provides good refactoring items.
But when to do "convert anonymous to inner" is better?
For Example:
new Thread(new Runnable() {
#Override
public void run() {
// do something
}
})
After Refactoring:
new Thread(new MyRunnable());
private static class MyRunnable implements Runnable {
#Override
public void run() {
// do something
}
}
As far as I know, The static method you should use to avoid Memory Leak. Eg:
new Thread(new Runnable() {
#Override
public void run() {
// do something long here
YourActivity.this.doSomething();
}
})
--> above code will make your app get memory leak error when you close your app when the thread is running.
However, with new refactor you can avoid memory leak easily:
private static class MyRunnable implements Runnable {
WeakReference<YourActivity> activity;
#Override
public void run() {
// do something long
if(activity.get() != null){
activity.get().doSomething();
}
}
}
It is much easier to create several instances of an inner class (by calling its' constructor) than creating several instances of an anonymous class.
A much easier question to answer is How are Anonymous (inner) classes used in Java?, which in short is to either quickly implement an interface (or abstract class) without adding much functionality to the interface (or abstract class) vs. wanting a strongly typed sub-class of another class which which will be constructed regularly.
A good example for interfaces/abstract classes you'd usually want to use an anonymous inner class are Runnables and most Listener interfaces, since they only serve as a wrapper for a piece of code "given" to an instance of another class. Good examples for inner classes are Fragments in android or custom controls (View in android), though refactoring those into separate classes can make them much more reusable.
A quick and dirty test is "Do I need create my own constructor for my inner class?", if the answer is "yes" than use a non-anonymous inner class.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I run into some code which contains anonymous classes. I haven't met with anonymous classes before, so I did some research on them.
My main area of interest is java, so I checked Oracle's tutorial of anonymous classes. I understand the mechanism and I see the point of the examples but in my opinion using anonymous classes makes the code hard to read and can cause a lot of headache.
Are there any cases when it is unavoidable to use anonymous classes or it is advised to use them instead of named classes?
Are there any cases when it is unavoidable to use anonymous classes
No, you can always just use a private inner class instead of an Anonymous class.
using anonymous classes makes the code hard to read and can cause a lot of headache
This very much depends on how you use anonymous classes. Consider the following example:
new Thread(new Runnable() {
#Override
public void run() {
// do something
}
}).start();
In this example you create a Runnable which is run by a thread. If you wouldn't use an anonymous class you'd have to write it as follows:
private class SomeClass implements Runnable {
#Override
public void run() {
// TODO Auto-generated method stub
}
}
and use it as:
new Thread(new SomeClass()).start();
With the first possibility you can directly see what that thread is doing, in the second possibility you'll first have to find the class that is used here.
Another advantage of anonymous classes. You can do the following:
// define some constant which can be used in the anonymous class:
final String someStr = "whatever";
new Thread(new Runnable() {
#Override
public void run() {
// use the String someStr directly
System.out.println(someStr);
}
}).start();
You can use the constant which is declared in the code where the anonymous class is defined. If you'd use a private inner class you'd have to give these constants to the constructor of the class in order to use them!
You can always avoid using of anonymous classes by defining new class implicitly. However in some cases it's better to use anonymous classes. Consider following example:
void main() {
new Thread(new Runnable(){
public void run() {
System.out.println("Hello world");
}
}).start();
}
Code snippet above is more readable and shorter then defining new class.
public class MyRunnable implements Runnable {
public void run() {
System.out.println("Hello world");
}
}
void main() {
new Thread(new MyRunnable()).start();
}
In Java 8 labmda can be used instead of anonymous class in some cases
Runnable task = () -> { System.out.println("hello world"); };
new Thread(task).start();
Are there any cases when it is unavoidable to use anonymous classes...
No. You could always define a named class for that. The point of annonymous classes is to make the code more concise and compact in situations in which you only need to use a class once.
it is advised to use them instead of named classes?
It depends on the context of the class being created.
if you are implementing interfaces having only one function (i.e Runnable) then using lambda expression instead of anonymous classes is not a bad choice.
lamba expression
A common situation when writing an Android app: scheduling a Runnable to make some drawing work on a View:
class MyView extends View {
...
private void start() {
final ScheduledExecutorService executor = Executors
.newScheduledThreadPool(1);
mMoverFuture = executor.scheduleWithFixedDelay(new Runnable() {
#Override
public void run() {
if (isOutOfView()) {
mMoverFuture.cancel(false);
}
postInvalidate(); // Can I do this?
}
}, 0, REFRESH_RATE, TimeUnit.MILLISECONDS);
}
...
}
Particularly, I am not sure if I can call MyViews method postInvalidate() from the thread's run(). Which rules should one follow when judging which variables and methods are available to an anonymous class object?
According to Java rules an instance of InnerClass has direct access to the methods and fields of its enclosing instance. If you have doubts you can check it in Oracle documentation
Method postInvalidate, in its turn, is designed especially to be invoked outside of UI thread so it also doesn't violate Android View's restrictions.
There are no rules. You can call any variables from parent class. In your case all you need to remember it is thread safety. Take care about this, if it is important for you.
This is a question about style. What is the cleanest solution to this case:
I have a Runnable class:
class R implements Runnable {
public void run(){
System.out.print("hello")
}
}
And another class that starts this class like this:
Thread t = new Thread(new R());
t.start;
My question is that if i need run to do something a bit more different depending on an radio button selected in the class that starts the thread what would be the best way to pass it on to the Runnable class?
Should i just make a constructor and add a Boolean witch action to perform? Or make a public boolean and set it to true false before running the thread? Or should i define an Enum in R class with the different actions and pass it on? Or some other way?
I would agree that the best way is for the Runnable's constructor to accept whatever parameters are required for execution. For example:
class R implements Runnable {
private final boolean myBool;
public R(boolean myBool) {
this.myBool = myBool;
}
public void run(){
if (myBool) {
System.out.print("hello");
} else {
System.out.print("goodbye");
}
}
}
In general, making public global variables (the other alternative you've mentioned) is bad practice. The method listed above ensures encapsulation; only the things that need to know about the value know about it. This ensures that as your system grows more complex, no other classes are messing up your values :-)
I have a method in my static state machine that is only used once when my application is first fired up. The method needs to be public, but I still want it hidden. Is there a way to use an annotation or something that will hide the method from the rest of the project?
You cannot make a public method hidden (unless you can declare it private). You can however put in a subclass and only let the users of the object know the type of the superclass, that is:
class A {
//Externally visible members
}
class B extends A {
//Secret public members
}
Then you instantiate the class B, but only let the type A be known to others...
Once you declare public method it becomes part of your class's contract. You can't hide it because all class users will expect this method to be available.
You could use package level instead of public. That way it can only be called by your application.
If a method is public, it can't be hidden. What you may really be looking for is just a way to restrict access to calling a method. There are other ways to achieve a similar effect.
If there are some things that your state machine does that are "only used once when my application is first fired up" it sounds a lot like those are things that could happen in the constructor. Although it depends on how complex those tasks are, you may not want to do that at construction time.
Since you said your state machine is static, is it also a Singleton? You could maybe use the Singleton Pattern.
public class SimpleStateMachine {
private static SimpleStateMachine instance = new SimpleStateMachine();
private SimpleStateMachine() {
super();
System.out.println("Welcome to the machine"); // prints 1st
}
public static SimpleStateMachine getInstance() {
return instance;
}
public void doUsefulThings() {
System.out.println("Doing useful things"); // prints 3rd
}
}
Here's some code for a client of this Singleton:
public class MachineCaller {
static SimpleStateMachine machine = SimpleStateMachine.getInstance();
public static void main(String... args) {
System.out.println("Start at the very beginning"); // prints 2nd
machine.doUsefulThings();
}
}
Note that the SimpleStateMachine instance isn't built until the first time your class is accessed. Because it's declared as static in the MachineCaller client, that counts as a "first access" and creates the instance. Keep this tidbit in mind if you definitely want your state machine to perform some of those initialization tasks at the time your application starts up.
So, if you don't want to turn your state machine class into a true singleton... you can use a static initialization block do your one-time tasks the first time the class is accessed. That would look something like this:
public class SimpleStateMachine {
static {
System.out.println("First time tasks #1");
System.out.println("First time tasks #2");
}
public SimpleStateMachine() {
super();
System.out.println("Welcome to the machine");
}
public void doUsefulThings() {
System.out.println("Doing useful things");
}
}
While we're at it, since you mentioned that it's a state machine... the Head First Design Patterns book does a nice, easily understandable treatment of the State Pattern. I recommend reading it if you haven't already.
The idiomatic approach to doing this is to use interfaces to limit the visibility of your methods.
For example, say you have the following class:
public class MyClass {
public void method1() {
// ...
}
public void method2() {
// ...
}
}
If you want to limit some parts of the project to only see method1(), then what you do is describe it in an interface, and have the class implement that interface:
public interface Method1Interface {
public void method1();
}
...
public class MyClass implements Method1Interface {
public void method1() {
// ...
}
public void method2() {
// ...
}
}
Then, you can limit the visibility of the methods by choosing to pass the class around either as a MyClass reference, or as a Method1Interface reference:
public class OtherClass {
public void otherMethod1(MyClass obj) {
// can access both obj.method1() and obj.method2()
}
public void otherMethod2(Method1Interface obj) {
// can only access obj.method1(), obj.method2() is hidden.
}
}
A bonus of this approach is that it can also be easily extended. Say, for example, you now also want to independently control access to method2(). All you need do is create a new Method2Interface along the same lines as Method1Interface, and have MyClass implement it. Then, you can control access to method2() in exactly the same manner as method1().
This is a similar approach to that advocated in #MathiasSchwarz's answer, but is much more flexible:
The independent access control described in the preceding paragraph isn't possible with Mathias' technique, due to Java not supporting multiple inheritance.
Not requiring an inheritance relationship also allows more flexibility in designing the class hierarchy.
The only change required to the original class is to add implements Method1Interface, which means that it is a very low-impact refactor since existing users of MyClass don't have to be changed at all (at least, until the choice is made to change them to use Method1Interface).
An alternative solution: You can make it private and create a invokeHiddenMethod(String methodName, Object ... args) method using reflection.
You said that your public method is used only once when the application is started up.
Perhaps you could leave the method public, but make it do nothing after the first call?
There is a (non-)keyword level package level visibility. Instead of public, protected, or private, you use nothing.
This would make the method or class visible to the class and others in the package, but would give you a certain modicum of privacy. You may want to look at What is the use of package level protection in java?.
Hmm... You want a private method, but want to access it outside?
Try do this with reflection.
http://download.oracle.com/javase/tutorial/reflect/index.html
I have seen many Java programmers do something like this:
public static void main(String args[]) {
new MyClass();
}
So basically they create just one object of the class. If there is a method which should run only once, I guess this approach can achieve that. Your method will be called from inside the constructor. But since I don't know how your app works, what are the constraints, so it is just a thought.
I'm currently taking a course in Java and I've run into some confusing code.
Example:
Runnable runnable = new Runnable()
{
public void run()
{
//doStuff
}
};
I don't really get what this code is doing.
How can the run method be associated with an instance of a class?
I googled "Runnable" and found out that it is an interface. Am I implementing the interface by declaring the run method between curly brackets ? Can this be done for any interface in java ?
I could use some links/explanations. Thank you!
It's an anonymous inner class that's implementing the interface Runnable. Yes, you can implement any interface this way, although there are reasons why you would or wouldn't in any given case (lack of reusability being a big one in the "wouldn't" column). More about anonymous classes here, but it's basically a convenient form of this:
// Define it
class Foo implements Runnable
{
public void run()
{
// Do stuff
}
}
// And then use it
Runnable runnable = new Foo();
...provided Foo is an inner (or "nested") class. More about nested classes here.
yes, you are implementing the interface by declaring the run. Yes it can be done for any interface.
This is typically done when you pass an implementation to a method that expects an argument of an Interface type, and you don't have a declared class that is appropriate. You can just implement the interface on the spot, and that code runs. Pretty neat.
I googled "Runnable" and found out
that it is an interface. Am I
implementing the interface by
declaring the run method between curly
brackets ? Can this be done for any
interface in java ?
Yes!
This code is instantiating an object which implements Runnable. Because we can't actually construct an interface, any code which attempts to do so must provide implementations for the interface's methods in curly brackets. We don't really get to see what class Java is creating to implement Runnable (these are abstract terms).
If you were to do the following:
Runnable runnable = new Runnable()
{
public void run()
{
System.out.println("I'm running");
}
};
runnable.run();
you would see "I'm running" as your output.
In some situation , this sample code will be useful .... test runna = new test()
class test implements Runnable{
test(){
Thread t = new Thread(this);
t.start();
}
#Override
public void run() {
// TODO Auto-generated method stub
while(true){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.print("asd");
}
}
}