Here's an excerpt from my code
package dictionary;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.regex.*;
public class IntelliCwDB extends CwDB {
public IntelliCwDB(String filename) {
super(filename);
}
#Override
public void add(String word, String clue) {
System.out.println("inelli");
}
}
And CwDB...
package dictionary;
import java.util.LinkedList;
import java.io.*;
import java.util.Scanner;
public class CwDB {
protected LinkedList<Entry> dict;
public CwDB(String filename) {
dict = new LinkedList<Entry>();
createDB(filename);
}
public void add(String word, String clue) {
System.out.println("cwdb");
dict.add(new Entry(word, clue));
}
protected void createDB(String filename) {
try {
BufferedReader f = new BufferedReader(new FileReader(filename));
while (f.ready()) {
this.add(f.readLine(), f.readLine());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
In the main() part I create a new IntelliCwDB object, which fires the execution of createDB().
The problem is that I want CwDB.createDB() to use it's own CwDB.add() method, not the one from IntelliCwDB. Is there any other neat solution than creating CwDB separately, then passing it into the constructor of IntelliCwDB just to rewrite the LinkedList<Entry> dict database?
You experienced one of the reasons why one should not call virtual methods from a constructor. For more details on this, see Effective Java 2nd Edition, Item 17: Design and document for inheritance or else prohibit it.
The simplest solution to your problem would be to split the base class method into a nonvirtual (final and/or private) one, and another, virtual, method, which calls the former in the base class implementation.
#aioobe was faster to provide an example to this :-)
You could solve it like this:
Create a private (or final) version of the CwDB.add, lets call it privateAdd.
Let the old add method in CwDB call this method instead.
Whenever you want to be sure that the CwDB-version of add is used, you simply call privateAdd instead.
Sample code
public class CwDB {
// ...
public void add(String word, String clue) {
privateAdd(word, clue);
}
private void privateAdd(String word, String clue) {
System.out.println("cwdb");
dict.add(new Entry(word, clue));
}
protected void createDB(String filename) {
// ...
// "Calling parent method from within the parent class" :-)
this.privateAdd(f.readLine(), f.readLine());
// ...
}
// ...
}
As #Péter Török correctly points out: You should never call a virtual method (directly or indirectly) from within a constructor. The reason is simple: The sub-class will get to run code before its super class (and itself) is initialized properly. (Whether or not it applies in this particular example stands to reason though.)
I would move the add method to addInternal in CwDB, and make a new add which calls addInternal. Then in the createDB method, call addInternal to get the correct method.
Eg.
class CwDB {
..
private void addInternal(String word, String clue) {
..
}
public void add(String word, String clue) {
addInternal(word, clue);
}
public void createDB(String filename) {
..
addInternal(w, c);
..
}
}
Related
For two utility classes with the same names, which contain only static methods, I proceeded as follows:
Simply imported the first
Created an instance of the second class.
Example:
package util1;
public class Utility {
public static void method() {
System.out.println("First Utility. static method");
}
}
package util2;
public class Utility {
public static void method() {
System.out.println("Second Utility. static method");
}
}
import util1.Utility;
public class Component {
private static final util2.Utility anotherUtility = new util2.Utility();
public static void usedByReflection() {
Utility.method();
anotherUtility.method();
}
}
Now I don't need to write a full second util-class name for invoke its methods, but maybe I did not foresee something...?
P.S:
The methods of the class Component are called through a reflection by a certain BlackBox. All the multithread-safe features are in BlackBox.
UPD: I have found better trick:
import util1.Utility;
public class Component {
private static final util2.Utility anotherUtility = null; // There are some changes
public static void usedByReflection() {
Utility.method();
anotherUtility.method();
}
}
Now I dont create new object, but is it possible to use it without any bugs?
IMO, this is confusing and could much more clearly be handled by something like:
public class CombinedUtilityComponent {
public static void usedByReflection() {
util1.Utility.method();
util2.Utility.method();
}
}
Or, better yet, in your code you can just fully qualify the class names and they become unique names without any confusing tricks.
Yes, this works. I wouldn't do it, though.
You're calling a static method as if it were an instance method. anotherUtility.method() has a useless reference to anotherUtility.
You also have an unnecessary instantiation of util2.Utility. This technique wouldn't work if the default constructor were disabled.
Is there a way to always execute a function before any other function of a class is called?
I have a class where I need to refresh some fields always before any function is called:
public class Example {
private int data;
public void function1(){
}
public void function2(){
}
//#BeforeOtherFunction
private void refresh(){
// refresh data
}
}
Because it seems to be bad programming, I don't want to call refresh at the beginning of every other function. Since other persons are going to work on this project as well, there would be the danger, that somebody extends the calls and doesn't call refresh.
JUnit has a solution for this with the #Before-Annotation. Is there a way to do this in other classes as well?
And by the way: If you know a programming pattern wich solves this problem in another way than executing a function everytime any function is called, that would be very helpful, too!
Use a dynamic proxy in which you can filter to those methods before which your specific "before" method should be called. And call it in those cases before dispatching the call. Please see the answer from How do I intercept a method invocation with standard java features (no AspectJ etc)?
UPDATE:
An interface is needed to be separated for the proxy. The refresh() method cannot remain private. It must be public and part of the interface (which is not nice here) to be able to be called from the proxy.
package CallBefore;
public interface ExampleInterface {
void function1();
void function2();
void otherFunction();
void refresh();
}
Your class implements that interface:
package CallBefore;
public class Example implements ExampleInterface {
#Override
public void function1() {
System.out.println("function1() has been called");
}
#Override
public void function2() {
System.out.println("function2() has been called");
}
#Override
public void otherFunction() {
System.out.println("otherFunction() has been called");
}
#Override
public void refresh() {
System.out.println("refresh() has been called");
}
}
The proxy which does the trick. It filters the needed methods and calls refresh().
package CallBefore;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ExampleProxy implements InvocationHandler {
private ExampleInterface obj;
public static ExampleInterface newInstance(ExampleInterface obj) {
return (ExampleInterface) java.lang.reflect.Proxy.newProxyInstance(obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(), new ExampleProxy(obj));
}
private ExampleProxy(ExampleInterface obj) {
this.obj = obj;
}
#Override
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
Object result;
try {
if (m.getName().startsWith("function")) {
obj.refresh();
}
result = m.invoke(obj, args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
} catch (Exception e) {
throw new RuntimeException("unexpected invocation exception: " + e.getMessage());
}
return result;
}
}
The usage:
package CallBefore;
public class Main {
public static void main(String[] args) {
ExampleInterface proxy = ExampleProxy.newInstance(new Example());
proxy.function1();
proxy.function2();
proxy.otherFunction();
proxy.refresh();
}
}
Output:
refresh() has been called
function1() has been called
refresh() has been called
function2() has been called
otherFunction() has been called
refresh() has been called
This may not solve your exact problem but at least could be a starting point if you are allowed considering a re-design. Below is a simple implementation but with some small touches I believe you can achieve a more elegant solution. BTW, this is called Dynamic Proxy Pattern.
First thing you need is an interface for your class.
public interface Interface {
void hello(String name);
void bye(String name);
}
public class Implementation implements Interface {
#Override
public void hello(String name) {
System.out.println("Hello " + name);
}
#Override
public void bye(String name) {
System.out.println("Bye " + name);
}
}
Then java.lang.reflect.Proxy class comes to help. This class is able to create an instance for a given interface at runtime. It also accepts an InvocationHandler which helps you to capture method calls and looks like this.
public class InvocationHandlerImpl implements InvocationHandler {
private final Object instance;
public InvocationHandlerImpl(Object instance) {
this.instance = instance;
}
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result;
try {
System.out.println("Before");
result = method.invoke(instance, args);
System.out.println("After");
} catch (Exception e){
e.printStackTrace();
throw e;
} finally {
System.out.println("finally");
}
return result;
}
}
After all your client code will look like this.
Interface instance = new Implementation();
Interface proxy = (Interface)Proxy.newProxyInstance(
Interface.class.getClassLoader(),
new Class[] { Interface.class },
new InvocationHandlerImpl(instance));
proxy.hello("Mehmet");
proxy.bye("Mehmet");
Output for this code is
Before
Hello Mehmet
After
finally
Before
Bye Mehmet
After
finally
I would define getters for every field and do the refreshment inside the getter. If you want to avoid unrefreshed access to your private fields at all, put them in a superclass (together with the getters which call refresh).
Depending on your project structure, it may be also sensible to introduce a separate class for all data that is regularly refreshed. It can offer getters and avoid that anyone accesses the non-refreshed fields.
Not in Java SE, but if you are using Java EE, you could use interceptors.
For standalone applications, you could consider using a bytecode manipulation framework, like javassist.
You can have a protected getter method for data. Access getData method instead of using data field. Child classes will see only getData and will have updated data every time.
public class Example {
private int data;
public void function1(){
}
public void function2(){
}
protected int getData(){
refresh();
return data;
}
//#BeforeOtherFunction
private void refresh(){
// refresh data
}
}
It is better to write another method which will be made protected(accessible to the child classes) which will call first the refresh method and then call the function.
This way the data would be refreshed before the function is called everytime(As per your requirement).
eg:
protected void callFunction1(){
refresh();
function();
}
Thanks,
Rajesh
You should use Decorator in this case. Decorator is a good choice for something like interceptor. Example here: https://msdn.microsoft.com/en-us/library/dn178467(v=pandp.30).aspx
So I have small interface
public interface IPlayersStorage
{
// other methods...
public boolean addException(final String nick);
// other methods...
}
and class "PlayersStorage" that implements it: (only used part)
public class PlayersStorage implements IPlayersStorage
{
private static final PlayersStorage inst = new PlayersStorage();
private final Set<String> exceptions = new HashSet<>(50);
#Override
public boolean addException(final String nick)
{
return ! this.exceptions.add(nick);
}
public static PlayersStorage getStorage()
{
return inst;
}
}
And in some place I use that method using that code:
for (final String player : this.cfg.getStringList("Exceptions"))
{
PlayersStorage.getStorage().addException(player);
}
And ProGuard change it to:
for (Iterator localIterator1 = this.cfg.getStringList("Exceptions").iterator(); localIterator1.hasNext();)
{
localIterator1.next();
PlayersStorage.getStorage(); // it's get object, but don't do anything with it...
}
The only possible fix that I found, is add static method to PlayersStorage
public static boolean staticAddException(final String nick)
{
return inst.addException(nick);
}
And then use it (instead of old code)
for (final String player : this.cfg.getStringList("Exceptions"))
{
PlayersStorage.staticAddException(player);
}
Then works... (ProGuard keep method call) but adding static methods for every method from interface isn't good idea.
ProGuard only removes method invocations if they don't have any effect (doesn't seem to be the case here), or if you have specified -assumenosideffects for the methods. You should check your configuration and remove any such option.
Alternatively, your decompiler may be having problems decompiling the code. You should then check the actual bytecode with javap -c.
Today while coding I began a deep dive into the world of reflection. I have messed with it in small bits and pieces before but never to this extent and no matter where I look I can find no answer to my question and so here I am! Currently what I am trying to do is use reflection with a class whose constructor requests a parameter but for ease of use I wish to use the super class of the parameter.
Here is the code causing problems with some explanations:
this.listener = (MyListener) listenerClass.getConstructor(MyAppState.class).newInstance(this);
The thing is that MyAppState is the class that all of my appstates extend from and each listener takes in its own specific AppState that extends MyAppState but has extra features different from each other. What I need to know is what I can put in my .getConstructor() to specify that the class I am passing in is the super of the parameter it wants.
Here is a theoretical example of the code:
this.listener = (MyListener) listenerClass.getConstructor(Class extends MyAppState.class).newInstance(this);
So is this possible or should I just work with my code to have a second constructor that accepts the MyAppState class, or something else along those lines.
Also, sorry if this is off topic but to prevent problems in the future, I am being told this question is subjective. Is there any way to word future questions to not be as subjective or is the method to figure out whether the question is subjective just a bit flawed?
[EDIT] As requested, a few more examples related to the question:
public MyAppState(Node screen, Class listenerClass)
{
this.screen = screen;
try
{
this.listener = (MyListener) listenerClass.getConstructor(MyAppState.class).newInstance(this);
}
catch (Exception e)
{
Logger.getLogger(MyAppState.class.getName()).log(Level.SEVERE, "The listener for the {0} appstate could not be created using reflection.", new Object[]{this.getClass().getName()});
System.exit(-1);
}
}
Above is the full parent class's constructor, the said class extends one more class but it contains no constructor and so I am not sure if it is needed. If it is please feel free to ask for it.
public class OptionsMenuState extends MyAppState
{
public OptionsMenuState()
{
super(new Node("Options Screen"), OptionsMenuStateListener.class);
}
That is one class and its constructor with pieces cut off to keep it short.
public class MainMenuState extends MyAppState
{
public MainMenuState()
{
super(new Node("Start Screen"), MainMenuStateListener.class);
}
Here is another class and its constructor.
[EDIT] As suggested, I created a program that roughly mimics what I am attempting to do.
/* package whatever; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
//This is what I want to do but I don't know how to have java allow me to pass in Greeting.
createObject(SimpleSentence.class);
createObject(DifferentSentence.class);
}
public static void createObject(Class theClass)
{
theClass.getConstructor(Greeting.class).newInstance(new Hello());
}
class SimpleSentence
{
Hello firstWord;
public SimpleSentence(Hello word)
{
firstWord = word;
}
}
class DifferentSentence
{
Howdy firstWord;
public DifferentSentence(Howdy word)
{
firstWord = word;
}
}
class Greeting
{
}
class Hello extends Greeting
{
}
class Howdy extends Greeting
{
}
}
Short answer is you can't. getConstructor(Class<?>...parametertypes) is very explicit because it needs to match exactly zero or one constructor only.
You will need to go through all the constructors to find one, that has a parameter that is assignable from MyAppState
e.g. outline:
final Constructor<?>[] ctrs = listenerClass.getConstructors();
for (Constructor<?> constructor : ctrs) {
if (constructor.getParameterTypes()[0].isAssignableFrom(MyAppState.class)) {
// use this one?
}
}
I'm working on a school assignment about Java reflection. The details are below:
Write a console program that asks the user for a class name, loads
that class and creates an instance of it. We assume that the class has
a constructor without any parameters. Then, the program prints out the
names and values of the public variables of the created object, and
also a list of the public methods that do not specify a parameter. The
program should let the user choose a method and execute that method on
the created object. Afterwards, the program should again show the
public variables with their values and allow the user to choose a
method, and so on. Use the following class to test your
implementation:
public class Counter {
public int c;
public void increment() { c++; }
public void decrement() { c--; }
public void reset() { c = 0; }
}
The problem I am having has to do with the following sentence: "list of the public methods that do not specify a parameter". Is there a way to list only methods with no parameters? I have used getMethods but I end up getting a lot of methods from the Object and Class superclasses with parameters.
For example the following code that I have written:
import java.lang.reflect.*;
import java.io.*;
public class Q1 {
public static void main(String[] args) {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.print("What class would you like to run? ");
String className = reader.readLine();
Class c = Class.forName(className);
Object o = c.newInstance();
for (Field f : c.getFields())
System.out.println(f);
for (Method m : c.getMethods())
System.out.println(m);
} catch(IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
Outputs the following:
What class would you like to run? Counter
public int Counter.c
public void Counter.reset()
public void Counter.increment()
public void Counter.decrement()
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
Is there a way to get only the ones with no parameters to be printed? Also is my interpretation of the assignment details right in the first place? Or does the phrase "public methods that do not specify a parameter" possibly mean something else and I have entirely the wrong idea?
Have you looked at the API for the Method class? There's a method called getParameterTypes() that has the answer for what you're looking for, and the API states explicitly what this will return if there are no parameters. Just call this in your for loop on the Methods returned and you should be in like flint.
Just use the Method class' getParameterTypes function. If the return value is 0 then there are no parameters to that function. Key part from the Java doc:
getParameterTypes
public Class[] getParameterTypes()
Returns an array of Class objects that represent the formal parameter types, in declaration order, of the method represented by
this Method object. Returns an array of length 0 if the underlying
method takes no parameters.
Returns:
the parameter types for the method this object represents