Find Method usages only for specified class in Intelij-Idea - java

I am using IntelliJ IDEA and I have problem with method usage finding.
Suppose I have interface Worker.
public interface Worker {
void startWork();
void endWork();
}
And I have two implementations.
public class Develper implements Worker {
#Override
public void startWork() {
System.out.println("Developer Start Working");
}
#Override
public void endWork() {
}
}
public class Qa implements Worker {
#Override
public void startWork() {
System.out.println("QA start Work");
}
#Override
public void endWork() {
}
}
I open the Developer class and trying to find usages of startWork().
I want only to view usage of the Developer.startWork() implemented method.
But when I find usages it shows both Developer and Qa.startWork() method usages. How can I avoid Qa.startWork() method usage when finding Developer.startWork() usages?

Using Ctrl+Shift+Alt+F7 (⌘+⇧+⌥+F7 for Mac) should show the prompt from Jim Hawkins answer.
See: https://www.jetbrains.com/help/idea/find-usages-method-options.html
When you search for usages of a method implementation with this dialog Ctrl+Shift+Alt+F7, IntelliJ IDEA will ask whether or not you want to search for the base method. With any other find usages actions such as Alt+F7 or Ctrl+Alt+F7, the base method will be included in the search results automatically.

I'm using IntelliJ IDEA 15.0.1 .
I think what you see when using the "find usages" functionality depends from the context.
If you place the cursor in method name Developer.startWork and invoke find usages , you should see a small dialog. You are asked "Do you want to find usages of the base method?" .
If you say "No", and in your sources you did only call the method via the base class or interface (Worker.start() in your example), IDEA doesn't show you any hits. Thats correct.
If you call the overridden method via Developer.startWork() , and press "No" in the dialog, then you will see the usages of the specific implementation.
Update:

After reading the answer from #JimHawkins, I think the elephant is still in the room :) The question is, do you want to see where Developer.startWork() is actually called, or do you want to see where it is statically referenced?
Eg:
Developer developer = new Developer();
developer.startWork(); // you want to find only this?
Worker worker = developer;
worker.startWork(); // ..or this as well?
The find usages method can only tell, where a given method is statically referenced, but not where it is actually used (that is determined runtime via the mechanism of polymorphism).

Related

Mediator Design Pattern: Why do classes have to inform mediator of their behaviours?

In the following class:
public class Ignition {
private EngineManagementSystem mediator;
private boolean on;
public Ignition(EngineManagementSystem mediator) {
this.mediator = mediator;
on = false;
mediator.registerIgnition(this);
}
public void start() {
on = true;
mediator.ignitionTurnedOn();
System.out.println("Ignition turned on");
}
public void stop() {
on = false;
mediator.ignitionTurnedOff();
System.out.println("Ignition turned off");
}
public boolean isOn() {
return on;
}}
I am unsure of the reason for these lines of code, e.g:
mediator.ignitionTurnedOn();
Why does this class need to invoke this method to inform the mediator that the ignition is on? would this mean that the method is invoked twice? Once by this method and then within the mediator itself?
The purpose of the mediator is to relay information between colleagues. You only have to inform the mediator of things that other colleagues in your system need to know about.
I would venture that in this system, there is perhaps another class perhaps called Engine which has a start() method also registered with the mediator.
When the Ignition start method calls mediator.ignitionTurnedOn(), most likely, the mediator then calls something like getEngine().start() from inside its ignitionTurnedOn() method.
Probably nothing is invoked twice here.
The purpose of the mediator is to provide highly cohesive services that allow to decouple the elements of the system. In terms of a car, the Ignition system would not need to know the details of what happens, e.g., a Choke is opened, a Starter is invoked, etc. as these details can change depending on the type of Engine system.
So, here's what happens likely:
To know for sure, you'd have to see how :Ignition is being called and what Mediator.ignitionTurnedOn() actually does.

Is there a way to export java functions to other packages within a library, but not to users of the library?

So, here's an example. I have a library in the package HTTP. I define sub-sections of the library in e.g. the package HTTP.TCPProtocol. Now I want to use TCPProtocol from the HTTP package, which means I have to make the TCPProtocol functionality public. At the same time, this functionality should not be exported to users of the library.
How do I do this? I don't want to shove my whole library into one package, as I feel the separate sub-packages really make the code more structured and navigation easier in eclipse. But browsing around, I couldn't find a method to expose functions within my project, but not export them outside my project.
EDIT: In light of me being able to come up with a better example, I'm updating the OP.
One simplistic approach is to whitelist your 'utility' methods so they take a caller instance of a certain type only.
package gameengine;
interface Whitelisted {} // marker
Then your method:
public void myMethod(Whitelisted caller, String arg)
And to invoke:
package gameengine.network;
class Foo implements Whitelisted {
...
Someclass.myMethod(this, "foo");
Check the caller's class to lock out all unwanted callers. The caller's class can be obtained from the stacktrace. In the example below, only instances of Bar will trigger the system.out.println, all all other will get an exception. You can even do package-level checks this way. Make sure that all allowed caller classes methods are not public, or they can call the doSomething method indirectly. You can even do deeper checks, by inspecting the stacktrace further.
Be aware though, that a skilled develper can circumvent anything you try do do in this matter. No solution is really "secure".
package one.two;
import one.Bar;
public class Foo {
public void doSomething() {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
StackTraceElement stackTraceElement = stackTrace[2];
String className = stackTraceElement.getClassName();
if (Bar.class.getName().equals(className)) {
System.out.println("jay!");
} else {
throw new RuntimeException("not allowed");
}
}
}
package one;
import one.two.Foo;
public class Bar {
void makeCall() {
new Foo().doSomething();
}
public static void main(String[] args) {
new Bar().makeCall();
}
}
Without seeing your dependencies, the only real advice the community can give you is to refactor your code. If something in your networking package needs to know about your game engine, it seems like you have a leaky abstraction. Hard to say without seeing your code.

Generic classes in my application

I've created a few minor apps for Android while learning. Being a PHP developer, it's a challenge to get used to it.
I'm especially wondering how I could define a couple of "general" functions in a separate class. Eg I have a function that checks if network connection is available, and if not, shows a dialog saying that the user should enable it. Currently, that function exists in several of my activities. Of course that seems strange - I suppose it would be more logical to define it once and include it in the activites where needed.
I tried putting it in a new class, and included that class in the original activity. But that failed since eg getBaseContext() is not accepted anymore.
I'm wondering how to go ahead. What should I be Google-ing for ? What is this mechanism called?
You need to create class with static methods. Like this
public class HelperUtils {
public static void checkNetworkConnection(Context ctx) {...}
}
Then you can call it from any place like this:
HelperUtils.checkNetworkConnection(this.getContext());
Assuming current class has Context.
You should read books on general OOP concepts where different type of methods are explained.
You can for example create a class - let's call it NetworkUtils. In this class you can create static method boolean isNetworkConnectionAvailable() and return true if is available and false otherwise. In this class you can create another static method void showNoConnectionDialog(Activity activity) - and in this method you create dialog starting with
public static void showNoConnectionDialog(Activity activity) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
//setting message, listener etc. and finally
builder.create().show();
}
In your activity, where you want to check and handle network connection you should call:
if (!NetworkUtils.isConnectionAvailable(getApplicationContext())) {
NetworkUtils.showNoConnectionDialog(YourActivityClassName.this)
}
I guess this should work.

Android: Parcelable.writeToParcel and Parcelable.Creator.createFromParcel are never called

I'm totally new to posting questions on here, however I have been reading a lot on here for years. Normally I always am able to find my answers by thoroughly searching the web, but this time I am at a loss...
After having spent yet another day of trying to figure out why this is not working I decided to ask for help, hoping you guys can give me a few pointers, or better, a solution.
The problem:
In an Android game I have come to the point where I have to make the application remember its state when a user e.g. presses the HOME-screen button. After some searches I realised that in order to make my classes initialize back to their appropriate states after re-opening the application I had to support the Parcelable interface to pass them with the Bundle.
In my onStop and onStart functions I respectively save and restore the game state to and from a Bundle, however when I call the putParcelable and getParcelable functions on the Bundle the object's writeToParcel and createFromParcel functions are never called.
Fearing that this may have been due to the relative complexity of the game I figured I had best create a very simple application to try to get it to work.
Based on many Parcelable examples I have seen online, this became my class:
public class ParcelableTest implements Parcelable {
int id;
public ParcelableTest(int newID)
{
id = newID;
}
private ParcelableTest(Parcel in) {
readFromParcel(in);
}
public void writeToParcel(Parcel out, int arg1) {
writeToParcel(out);
}
public void writeToParcel(Parcel out) {
Log.v("ParcelableTest","Writing to parcel");
out.writeInt(id);
}
public void readFromParcel(Parcel in) {
id = in.readInt();
}
public int describeContents() {
return 0;
}
public static final Parcelable.Creator<ParcelableTest> CREATOR = new
Parcelable.Creator<ParcelableTest>() {
public ParcelableTest createFromParcel(Parcel in) {
Log.v("ParcelableTest","Creating from parcel");
return new ParcelableTest(in);
}
public ParcelableTest[] newArray(int size) {
return new ParcelableTest[size];
}
};
}
And from my Main activity I would call the following functions to save / restore the data:
public Bundle saveToBundle(Bundle savedState)
{
savedState.putParcelable("Test1",mTest1);
savedState.putParcelable("Test2",mTest2);
return savedState;
}
public void restoreFromBundle(Bundle savedState)
{
mTest1 = savedState.getParcelable("Test1");
mTest2 = savedState.getParcelable("Test2");
}
But for some reason neither of the functions (with the putParcelable and getParcelable functions) will result in the appropriate Parcelable calls in my test class.
The strangest thing is that it does somehow read the correct values (I have tried with more variables in the class), but my debugging and my log shows that tha application never gets to writeToParcel and createFromParcel.
What am I missing here?
Any help / thoughts would be appreciated.
Apparently the Android Bundle class does not adhere to the parcelable protocol that instead is followed during IPC marshalling.
Instead, it seems like the Bundle implementation just writes and reads the Parcelable object into its own internal map by means of reflection. From a test we did, it seems that the Bundle writes/reads every field defined in your Parcelable-derived class, just because you have declared those fields.
Technically, the documentation doesn't say that writeToParcel or createFromParcel are called from onSaveInstance. As a matter of fact, if you check the savedState in your code you are going to find that it is exactly the same object instance in both the save and the restore cases; it makes sense to avoid serialize-deserialize if you can. OTOH, the documentation doesn't say either that serialization is not done. The conclusion should be that you shouldn't depend on either case, just assume that you get the correct bundle.
Also, you may want to check http://developer.android.com/guide/topics/resources/runtime-changes.html
I confirm what superjos said.
On the saveToBundle event, Android bundle just stores the class's members per reflection and doesn't call the Parcelable functions.
I have lost one day on this problem! sad....
This is really bad .... This means you potentially stores a huge amount of data for nothing using this way.

Java: Is there support for macros?

I am just curious on how people solve this. I often write the same type of code all the time. For instance:
new Thread() {
//...
//...
//...
//Change this line
//...
//...
}.start();
I keep changing the line where it says "Change this line" and then starting a thread. This change can be one line or a few lines. How would I go about compacting this code?
Well, I guess you could run your java files through the C preprocessor...
You can use the template pattern to create a base class that contains the common code. For example:
public abstract class ThreadTemplate extends Thread
{
public void run() {
//reusable stuff
doInThread();
//more resusable stuff
}
abstract void doInThread();
}
Then starting a thread with the boilerplate code is as easy as:
new ThreadTemplate{
void doInThread() {
// do something
}
}.start();
Also, a less elegant solution to save yourself some typing is to use the templating feature of your ide. You can find some info on setting them up in Eclipse here and you can find a list of useful ones at Useful Eclipse Java Code Templates
One technique is to put the code in an anonymous inner class, and pass that to a method that does the rest.
interface SomeInterface {
void fn();
}
executeTask(new SomeInterface {
public void fn() {
// Change this line.
}
});
private void executeTask(final SomeInterface thing) {
Thread thread = new Thread(new Runnable() { public void run() {
//...
//...
//...
thing.fn();
//...
//...
}});
thread.start();
}
Generally it isn't a good idea to extend Thread or other classes if it is unnecessary.
It's possible to use Java annotations to generate boilerplate code. Writing your own annotation processor is not hard.
If it is something that you use in many projects, I would set this up in your IDE. For instance I use eclipse and if you go to
Window->Preferences->Java->Editor->Templates you can setup your own templates, and then have them auto complete. For instance I always start typing sysout and then press tab, and eclipse has a built in template to replace that with System.out.println();
There are many pre-built templates in eclipse, so you could look at those for examples on syntax, if that is the IDE you use, if not there may be something similiar in other IDE's
This is very useful, and you could create one for any boiler code you find yourself writing a lot.
Nope, no macros. For this case, the closest you can get is to create new Runnable instance and pass it to either a function of your own creation or an ExecutorService, which will start the task for you.
With Java, there's no good way to get rid of this "boilerplate" code, mainly because you can't pass pointers to functions; everything needs to be an object.
In the case of a Thread, you can pass any object that implements Runnable to its constructor.
So, the solution is to create your own class:
public class MyClass implements Runnable {
void run() {
// change this line
}
}
Unfortunately, run isn't static, so you'll have to create an instance of MyClass first:
new Thread(new MyClass()).start();
You could also add variables to MyClass and a constructor so you can pass arguments to it.
Edit: If you need more than just the start method, you can also subclass Thread itself.

Categories

Resources