Is it possible in Java, to declare a method with a string instead of an identifier?
For example can I do something like the following:
class Car{
new Method("getFoo", {
return 1+1;
});
}
//Use it
Car car = new Car();
car.getFoo();
EDIT: I am adding a Purpose WHY I need this. In order to not hardcode method names when using Jersey and its UriBuilder, which requires a method name:
https://jsr311.dev.java.net/nonav/releases/1.1/javax/ws/rs/core/UriBuilder.html
See path() method with signature:
public abstract UriBuilder path(java.lang.Class resource,
java.lang.String method)
throws java.lang.IllegalArgumentException
So then I may just use string constants and not worry that the method name will ever be different from the string that I am passing to the path() method.
I hope my question is clear, if not - let me know and I can clarify it.
It's not possible in the way you described.
The closest thing is probably the asm library to create java bytecode.
As per the purpose, why don't you just have a single method and let it act/behave differently depending on the caller and the parameters?
It's indeed not great to have the method name as string in the code, but if feel the usage of reflection from your side and from jax-rs side should compensate so that this does not happen.
Let me clarify. I guess you are using UriBuilder because you want to expose a service, or something similar. If you reflect on the class and list the method, then pass their name in UriBuilder, which also reflect on the class, the method is never explicitly mentioned in the source.
I'm not familiar with jax-rs though, and without knowing more about what you exactly try to achieve (your edit does provide a bit more information, but does not explain the end goal you have in mind), I don't know if that makes sense. But it could be a track to follow.
If you can consider using another language on the JVM, Groovy can do that.
Related
The details:
I have been given a Java program in which I need to fill in some code. The main idea of the program is to get used to interfaces and static methods in them. For the past 6 hours I have been watching countless of videos regarding interfaces and static interfaces and I still feel somewhat clueless to what I am supposed to do.
public interface Util {
static Util create() {
//TODO: this line needs to be replaced with the constructor of a concrete implementation
throw new IllegalStateException("Not implemented yet!");
}
Instruction forSymbols(Symbol first, Symbol last);
Symbol forToken(String token);
Supplier<Integer> buildPipe(InputStream input);
Consumer<Integer> buildPipe(OutputStream output);
String getInstructionCode(Instruction instruction);
Optional<Instruction> getInstruction(String code);
}
This is a snippet of the util interface for a program that will be relevant for having a Ook! translator and is supposed to have a lot of useful tools for other classes.
Now, my goal is to understand what I am supposed to do.
What I tried:
Considering I don't know what I need to do, I don't know what I have to code. I understand that an interface is a sort of template for classes. A static method in an interface is the part that I don't understand yet: I have been told that a static method in an interface is something that doesn't have to be implemented in other classes. In my case, the static method create() is "supposed to be a concrete instance of the util object". So, if I get this right, due to it being static, there would be one shared instance of util.
Afterwards, if a class has the prompt "Instruction instruction = util.forSymbols(Symbol.Point, Symbol.Point);" after Util.create() has been used, I would have defined instruction using util's forSymbols method.
I do not know if I am good at conveying just what I need. I per sé understand what a constructor is, I understand what an interface is, I understand what static does, but I don't understand what I have to insert into the create() method. Heck, I don't even want a direct code solution to my problem, I just want to understand what I am supposed to code.
That being said, if anyone could give me an example of an interface working in a similar fashion as my code above that makes it clear just what exactly the static part in an interface does aswell as help me out with my describes issues, I would be tremendously thankful. Also, I hope that my issue description is alright.
That being said, thank you for trying to help me and thanks to all possible answers.
No, the interface can't keep state, so there isn't anywhere for the shared instance to hang out. This is not a way to implement a singleton. It must be a factory method. I think adding a method like this is confusing and probably a bad idea because it ties together the interface and the implementation in an inflexible way. you're expected to create something that implements Util, so there is going to be a constructor call for that class implementing Util. Otherwise it's not clear.
Another sign this is a bad idea is obviously Util doesn't have any instance methods so isn't usable as an object; either a) there is no state and creating an object is pointless or b) the object returned has to be cast to something else to be useful. Casts are bad, for the most part; they mean we're not benefiting from using the type system.
An interface is like a mask an object wears to keep users of it from seeing anything on it except what is on the interface. But allowing static methods is kind of a bolted-on feature that doesn't have much to do with interfaces (except that classes that implement the interface can call them without having to reference the interface).
Originally in Java you could put static methods only in classes, not in interfaces. There was an idea of a utility class, which was just a dumping ground for people to put static methods, and which didn't have any purpose as a class otherwise. Then there was a change to the language so you can put static methods on interfaces and not have to have a class involved. That's all putting static methods on an interface buys you, you can add only static methods because there is no mutable state allowed.
These methods outlined for you should all be things you can implement with only passed in arguments and local variables, without keeping any state outside of the scope of the method implementation.
I've tried to give you some idea of what is possible and what isn't, once that is clear you can ask your instructor some more focused questions about what you need to do.
I agree with Nathan Hughes. This an ill-conceived design, on the face of it.
But to cut to the chase, here is an example of you could complete that static method:
static Util create() {
return new OookUtil();
}
where
public class OookUtil implements Util {
public OookUtil() { ... }
// methods implementing the Util API for the Oook case.
}
Reviewing this we can immediately see one of the problems with the interface design. We have hard-wired a specific implementation class into the interface. That is most likely a bad idea.
Could we do any better? Well ... maybe ...
The Java SE class libraries have a concept of a Java Service Provider Interface or SPI. An SPI allows different providers to be selected depending on what is available at runtime, and so on. The idea is that SPI code does a runtime classpath search looking for all classes that implement the SPI (e.g. your Util). Then it selects the "best" according to (typically) runtime configurable criteria.
That logic would be implemented in your create method. The method would then instantiate the chosen class reflectively and return the instance. In its simplest form (ignoring the classpath search aspect) it might be something like this:
static Util create() {
String classname = System.getProperty("yourapp.utilclass");
Class<?> clazz Class.forName(className);
return (Util) clazz.newInstance();
}
In this illustration are getting a classname from the system properties. It could be set by running the application with a -D option; e.g. -Dyourapp.utilclass=yourapp.OookUtil.
The above code needs some exception handling ... which I will leave for you to figure out.
Maybe that is what your instructor is getting at. But if so, he or she should have explained more clearly what was expected.
I have a set of similar classes that all implement a function of the form
public static ClassA convertToClassA(Obj A)
public static ClassB convertToClassB(Obj B)
I want to loop through a list of classes and call this function that takes one argument of Obj in each class. How do I do this given each function is named differently?
Thanks for the help.
Class cls = Class.forName("ClassA");
String methodName = "convertTo" + cls.getSimpleName();
Method method = cls.getDeclaredMethod(methodName, new Class[]{Obj.class});
// If the underlying method is static, then the first parameter is ignored. It may be null as illustrated below.
method.invoke(null, your_object);
Create common interface with your method signature and let your invokable classes implement it, later on you can iterate over your objects as over instances of interface and call methods from it so no problem.
HOWEVER I am starting to think you want to call method without knowing it's name AT ALL - the only knowlage of target method is the number and type of arguments. Well that indeed IS impossible via reflection BUT, it will be innacurate if similar methods signatures will be present. Anyway, don't know what are you trying to do, but your project is badly designed from the ground (no interfaces, poor inharitance I guess etc.)
take a look at the reflection package. it provide methods to get back all the methods an instance has provide.
The apache common's BeanUtil (http://commons.apache.org/beanutils) also provide some util method doing similar things.
The subject says it already:
I am thinking right now about following design-problem: I define an interface for a specific type of object that contains various methods.
Now i have the problem, that different implementations of this interface, need additional/different method-parameters (because the way they are implemented makes this necessary), which i cannot incorporate into the interface because they are not common to all interface-implementations.
Now i realize that interface implementations could come with their own property-files, loading their additional parameters from there, but what if these parameters need to be passed in at runtime?
Currently i can only think of passing in a Map<String, Object> parameters to overcome this problem - since JDK-Classes like DocumentBuilderFactory are doing something very similar by providing methods like setAttribute(String attName, Object attValue) this
seems like a feasible approach to solve this problem.
Nevertheless i would be interested in how others solve issues like this, alternative ideas?
I dont want to derive from the interface and add additional methods, since in my case i would then have to throw NotImplementException from the methods of the base interface.
UPDATE:
What could be eventual problems of the Map-approach? Implementing classes are free to ignore it completely if they cant make use of additional parameters.
Others might check if the Map contains the desired parameter-names, check the type of their values and use them if valid, throw an exception if not.
I have also seen this being used for the abstract class JAXBContext, so it seems to be a common approach..
UPDATE:
I decided to go for the map-approach, since i dont see any obvious disadvantages and it is being used in the JDK as well (yes, i know this does not necessarily mean much :)
Since i cannot accept an answer on this question, i will just upvote. Thanks for your input!
regards,
--qu
You should just initialize each inheritor with its own specific required parameters and let the interface method remain parameter-less, as in:
Interface Runnable:
public interface Runnable {
public abstract void run();
}
Implementation:
public class MyRunnable {
private final String myConcreteString;
public MyRunnable(String myConcreteString) {
this.myConcreteString = myConcreteString;
}
public void run() {
// do something with myConcreteString
}
}
The point of the interfaces is to have something that is common to all implementations. By trying to do this you destroy the whole reason why interfaces exists.
If you absolutely must do that there is a simple enough way that I have used before.
My answer is in C++ because I'm just not that fluent in other languages. I'm sure there are ways to implement this in java as well.
SomeMethod(void* parameterData);
void* parameterData is a pointer to a struct containing your data. In each implementation you know what you are receiving. You can even have a enum to tell you what kind of data you are receiving.
SSomeData* data = (SSomeData)parameterData
EDIT:
Another approach would be to create a new interface for the parameters: IParameterData.
Inside that interface you have 2 methods: GetParameter(name) and SetParameter(name).
For each implementation of your primary interface you create a implementation of IParameterData.
I hope it helps
couldn't you design subinterfaces that extend your (super)interface?
anyhow I see a design problem if you need a method with different parameters depending on the implementation!
edit: code to clarify
interface CommonBehaviour
{
void methodA(int aParam);
}
interface SpecificBehaviour extends CommonBehaviour
{
void methodB(int aParam, int anotherParam);
}
class SpecificBehaviourImpl implements SpecificBehaviour
{
void methodA(int aParam)
{
//do something common
}
void methodB(int aParam, int anotherParam)
{
//do something specific
}
}
CommonBehaviour myObj = new SpecificBehaviourImpl();
EDIT: You may benefit from the Command pattern:
"Using command objects makes it easier to construct general components that need to delegate, sequence or execute method calls at a time of their choosing without the need to know the owner of the method or the method parameters."
(source: wikipedia)
I don't think the Map approach to be any good, I may accept it as a fix of existing code that would allow you to have any parameter number and type, but without formal checks! You're trying to define a common behavior (interface methods) given a variable, runtime, state.
You should introduce parameter object representing a super-set of possible arguments.
In your place, I would consider finding appropriate design pattern to your problem, rather then try to bend the interface methods to suit your needs. Look into Strategy Pattern for starters.
Can you invert the problem, and implement an interface on the user of these objects which they can query for the additional parameters?
So, when you instantiate these objects implementing the common interface, you also pass in (e.g. to their constructor) an object which provides a way of accessing the additional parameters they might require.
Say your interface has a method 'doSomething' taking parameter 'a', but you have an implementation that needs to know what 'b' is inside this 'doSomething' method. It would call 'getB' on the object you provided to it's constructor to get this information.
For example, suppose I have the following base class for which I cannot modify the source code
class Base {
def someMethod = ...
}
If I define a sub class
class Sub extends Base {
override def someMethod = ...
}
when I do
val sub = new Sub
Then I automatically "know" when someMethod has been called because sub.someMethod is triggered. However I would like to avoid subclassing so I was wondering if there was some technique whereby I could do
class NotSubclass {
val Base = new Base
}
or similar
And somehow "attach" someMethod from Base so that NotSubclass would "know" when someMethod was called. To clarify someMethod is called externally I never make the call in my own code.
If you are modifying the behaviour of a class for which you don't have the source code, then you could try looking into Aspect-Oriented programming.
Aspects allow you to 'wrap' a method call so that you can log information, or modify the input parameters or return values, or even just replace the method call altogether.
If all you want to do is log information, then this would be a good way to go. However, Aspects can lead to code which is very hard to understand and follow if you use them everywhere, so be sure that it fits your use case.
You will need to define a pointcut for the method you are interested in.
The Scala-IDE uses aspects to weave code into the JDT, it uses AspectJ, so it does work with Scala.
If the method belongs to an interface you can reimplement that and wrap Base. Otherwise you are out of luck.
You mean like this?
class NotSubclass {
val base = new Base
def someMethod = base someMethod
}
I guess you could do it using byte code manipulation. PowerMock allows to mock constructors, so I'd guess the same technique could be used to replace the byte code of Base with something that does whatever you need to get done.
This approach of course will:
be extremely confusing for anybody being not aware of it.
fail if you don't have the classloaders under your control.
might break legal constraints
is just generally a bad idea for production code.
Is there a way to mock object construction using JMock in Java?
For example, if I have a method as such:
public Object createObject(String objectType) {
if(objectType.equals("Integer") {
return new Integer();
} else if (objectType.equals("String") {
return new String();
}
}
...is there a way to mock out the expectation of the object construction in a test method?
I'd like to be able to place expectations that certain constructors are being called, rather than having an extra bit of code to check the type (as it won't always be as convoluted and simple as my example).
So instead of:
assertTrue(a.createObject() instanceof Integer);
I could have an expectation of the certain constructor being called. Just to make it a bit cleaner, and express what is actually being tested in a more readable way.
Please excuse the simple example, the actual problem I'm working on is a bit more complicated, but having the expectation would simplify it.
For a bit more background:
I have a simple factory method, which creates wrapper objects. The objects being wrapped can require parameters which are difficult to obtain in a test class (it's pre-existing code), so it is difficult to construct them.
Perhaps closer to what I'm actually looking for is: is there a way to mock an entire class (using CGLib) in one fell swoop, without specifying every method to stub out?
So the mock is being wrapped in a constructor, so obviously methods can be called on it, is JMock capable of dynamically mocking out each method?
My guess is no, as that would be pretty complicated. But knowing I'm barking up the wrong tree is valuable too :-)
The only thing I can think of is to have the create method on at factory object, which you would than mock.
But in terms of mocking a constructor call, no. Mock objects presuppose the existence of the object, whereas a constructor presuppose that the object doesn't exist. At least in java where allocation and initialization happen together.
jmockit can do this.
See my answer in https://stackoverflow.com/questions/22697#93675
Alas, I think I'm guilty of asking the wrong question.
The simple factory I was trying to test looked something like:
public Wrapper wrapObject(Object toWrap) {
if(toWrap instanceof ClassA) {
return new Wrapper((ClassA) toWrap);
} else if (toWrap instanceof ClassB) {
return new Wrapper((ClassB) toWrap);
} // etc
else {
return null;
}
}
I was asking the question how to find if "new ClassAWrapper( )" was called because the object toWrap was hard to obtain in an isolated test. And the wrapper (if it can even be called that) is kind of weird as it uses the same class to wrap different objects, just uses different constructors[1]. I suspect that if I had asked the question a bit better, I would have quickly received the answer:
"You should mock Object toWrap to match the instances you're testing for in different test methods, and inspect the resulting Wrapper object to find the correct type is returned... and hope you're lucky enough that you don't have to mock out the world to create the different instances ;-)"
I now have an okay solution to the immediate problem, thanks!
[1] opening up the question of whether this should be refactored is well out of the scope of my current problem :-)
Are you familiar with Dependency Injection?
If no, then you ceartanly would benefit from learning about that concept. I guess the good-old Inversion of Control Containers and the Dependency Injection pattern by Martin Fowler will serve as a good introduction.
With Dependency Injection (DI), you would have a DI container object, that is able to create all kinds of classes for you. Then your object would make use of the DI container to instanciate classes and you would mock the DI container to test that the class creates instances of expected classes.
Dependency Injection or Inversion of Control.
Alternatively, use the Abstract Factory design pattern for all the objects that you create. When you are in Unit Test mode, inject an Testing Factory which will tell you what are you creating, then include the assertion code in the Testing Factory to check the results (inversion of control).
To leave your code as clean as possible create an internal protected interface, implement the interface (your factory) with the production code as an internal class. Add a static variable type of your interface initialized to your default factory. Add static setter for the factory and you are done.
In your test code (must be in the same package, otherwise the internal interface must be public), create an anonymous or internal class with the assertion code and the test code. Then in your test, initialize the target class, assign (inject) the test factory, and run the methods of your target class.
I hope there is none.
Mocks are supposed to mock interfaces, which have no constructors... just methods.
Something seems to be amiss in your approach to testing here. Any reason why you need to test that explicit constructors are being called ?
Asserting the type of returned object seems okay for testing factory implementations. Treat createObject as a blackbox.. examine what it returns but dont micromanage how it does it. No one likes that :)
Update on the Update: Ouch! Desperate measures for desperate times eh? I'd be surprised if JMock allows that... as I said it works on interfaces.. not concrete types.
So
Either try and expend some effort on getting those pesky input objects 'instantiable' under the test harness. Go Bottom up in your approach.
If that is infeasible, manually test it out with breakpoints (I know it sucks). Then stick a "Touch it at your own risk" comment in a visible zone in the source file and move ahead. Fight another day.