I currently have this code:
public class Pants {
public static void main(String[] args) {
Pants pants = new Pants();
pants.eat(10, 10.3, "Nice.");
Object[] params = {(long)10, 10.3, "Nice."};
Method eatMethod = pants.getClass().getMethods()[0];
try
{
eatMethod.invoke(pants, params);
} catch (IllegalAccessException | InvocationTargetException e)
{
e.printStackTrace();
}
}
public void eat(long amount, double size, String name) {
System.out.println("You ate");
}
}
It always throws
IllegalArgumentException: wrong number of arguments.
This happened with other methods too. I used the same parameters in eat() as in method.invoke, and the types are the same. The error is thrown on
eatMethod.invoke(pants, params);
As the comments say. We don't know wich method is pants.getClass().getMethods()[0]. Try to get the name with eatMethod.getName() and see if is really the method eat. If
not you can try with this.
java.lang.reflect.Method method;
method = pants.getClass().getMethod("eat", Long.class, Double.class, String.class);
.
.
.
method.invoke(pants,params );
Also... Checking the Java Docs The methods are never sorted
The elements in the returned array are not sorted and are not in any
particular order.
So sometimes your code might work and sometimes not.
It turns out that when I used getMethods()[0], I was getting the main method and calling that, which obviously has no parameters so it didn't work. Ideally I should've used
getMethod("eat", long.class, double.class, String.class)
which does work.
Related
So, I want to write these kind of things for my code, but there's too much code for one variable. How can I use modern Java for solving this problem shorter or cleaner? Moving it in the separate method doesn't solve the problem, because I still need to check the variable for null, which is wordy and adds extra method that used only once. It is possible to use Optionals here? Seems like return prevents this. Maybe there's the way for collapsing this thing into one for many variables like the foo described below? I don't know, just something to make it more readable and clean.
Foo foo;
try {
foo = FooProvider.getFoo(...);
} catch (FooProvidingException e) {
System.err.println("Foo exception: " + e.getMessage());
return;
}
// use foo, maybe in another method (when foo is the field).
I know, this question may be opinionated, but any help would be a valid answer.
Sorry for my poor english and thanks in advance!
What you're asking is not very clear, so I don't know at which extent my answer will be meaningful.
If I understand well, you have fields of any type (Foo, Bar...) and you would like to instantiate them using whatever kind of provider you wish, which can throw an exception while providing.
So at first, I don't think that you should return if an exception is thrown by the provider, but rather re-throw it or handle it. Because if you had an exception while getting your Foo and so you actually don't have a Foo, why would you continue (or why wouldn't you try to handle it somehow)?
Now this said and assuming that re-throwing/handling is taken care of, then I would define a ThrowingSupplier functional interface:
#FunctionalInterface
public interface ThrowingSupplier<T, E extends Exception> {
T get() throws E;
}
... and then I would create a static method like this:
public static <T, E extends Exception> T provide(ThrowingSupplier<T, E> supplier) {
try {
return supplier.get();
} catch (Exception e) {
System.err.println("Exception: " + e.getMessage());
throw (E) e;
}
}
So at that point, I would be simply calling this utility method every time that I want to execute such kind of operation:
Foo foo = provide(() -> FooProvider.getFoo(...)); //either creates a Foo, or prints and re-throw a FooProvidingException
Bar bar = provide(() -> BarProvider.getBar(...)); //either createa a Bar, or prints and re-throw a BarProvidingException
Integer myInt = provide(() -> 3);
String myStr = provide(() -> "hello");
//... and so on
But of course, at least once you'll have to extract the logic. Then it's all about extracting it in a way that it becomes generic and doesn't need to be repeated for each distinct type of object.
I am also not sure what the end-goal here is but, as I understand it, here's a simpler version of achieving the following:
Declaring and initializing the variable(s)
Fetching values for it with a service provider
Handling any exceptions thrown by this (or if the value is null) and exiting method
Continuing execution if everything is as expected
public static void main(String[] args) {
Foo foo1, foo2, foo3, foo4;
try {
foo1 = Optional.ofNullable(FooProvider.getFoo()).orElseThrow(new FooProviderException(1));
foo2 = Optional.ofNullable(FooProvider.getFoo()).orElseThrow(new FooProviderException(2));
foo3 = Optional.ofNullable(FooProvider.getFoo()).orElseThrow(new FooProviderException(3));
foo4 = Optional.ofNullable(FooProvider.getFoo()).orElseThrow(new FooProviderException(4));
// this works in or out of try/catch block
foo1.printName();
foo2.printName();
foo3.printName();
foo4.printName();
} catch (FooProviderException fpe) {
System.out.println("Exception: " + fpe);
return;
}
// this works in or out of try/catch block
foo1.printAgain();
foo2.printAgain();
foo3.printAgain();
foo4.printAgain();
}
I feel like I have had to unlearn something about programming lately. I keep going in circles.
I have a try catch in the method I want to use an AggregationOutput object. After the catch, I want to return what I hope are the values of the field I am looking for. That values are what I obtain from an aggregate method, which I can't find any way of storing other than AggregationOutput object.
Something like this:
List<DBObject> results = new ArrayList<DBObject>();
AggregationOutput output = new AggregationOutput(results);
try
{
or
AggregationOutput output = new AggregationOutput(null);
try
{
I am not able to create an AggregationOutput WITHOUT immediatly storing in it the values of the aggregate method. Like this:
AggregationOutput output = collection.aggregate(pipe);
This seems counter intuitive at the very least, if not plaing wrong, which makes me suspect I'm missing a BIG concept which isn't allowing me to use this method (aggregate) properly.
I would like to know what that object need to be declared on it's own, so I can declare, go into the try, instance the object, and then after the catch, return said object.
If there is any other way of doing this, without using AggregationOutput, I would also like to know, because I do not find any way.
edit:
#GET
#Path("/get/{item}/{id}")
#Produces(MediaType.APPLICATION_JSON)
public String get( #PathParam("item") String item, #PathParam("id") String id) {
AggregationOutput output;
try
{
List<DBObject> result = new ArrayList<DBObject>();
output = new AggregationOutput(result);
//here I would operate with the output, then return the result as I usually do, an array or some other object that can be transformed into json
maybe this is worth a try.
instead of doing
public String get()
{
try {}
catch() {}
}
try doing
public String get() throws ExceptionName {}
//assuming you will use get in main
public static void main (String [] args)
{
try { get(); }
catch (ExceptionName e) {}
}
otherwise link me the code and i will try debugging it at my end.
First, I know the Title is a bit ambiguous. Actually I don't know how to write it better!
Second, I will describe the problem.
Situation:
I am practicing on an online judge (OJ), so in case of wrong output, the OJ shows me the test case which makes my code to fail. Normally, I can copy my code and paste it into Eclipse, then call my function with that test case and debug my code.
But the problem when the test case is a multiple calls for my function (Like testing an enhanced version of a priority queue), let's assume there were n calls till the fail of the code. So to debug the code, I will have to call the function say n times! Which is not logical!
Function the OJ will call:
public void enqueue (int value)
{
// implementation
}
public int dequeue ()
{
// implementation
}
Test case makes the code to fail:
Last executed input: enqueue(5, 3), enqueue(51, 60), enqueue(0, 14), enqueue(364, 16),... dequeue(),...
Action:
I need a way to call the function with an array of test cases in order to be able to debug the code.
OR
By some way call the function with its parameter directly from the string. Something like invoke("enqueue(5, 3)");
After some investigation, I found a way to do the Action I need by using Java Reflection Also a helpful thread What is reflection and why is it useful?
I managed to develop a tool, here you are the steps:
Copy the test case in a String
Split the string on each function call
Remove the function name from each call, and store them in array of String in order.
Split the parameter
Now I have 2 arrays of integers for param1 and param2, and an array of String for invokations
I used Reflection in order to be able to call the methods from a string of calls, inside a for loop.
Then we have this
public class Test
{
public static void main(String[] args)
{
String testCase = "enqueue(5, 3), enqueue(51, 60), enqueue(0, 14), enqueue(364, 16), dequeue()";
// Prepare parameters and invocations
int[] param1; // assuming it is ready
int[] param2; // assuming it is ready
String[] calls; // assuming it is ready
try
{
Class calledClass = Class.forName("OJ.Prob3");
Method calledMethod1 = calledClass.getDeclaredMethod("enqueue", String.class, int.class);
Method calledMethod2 = calledClass.getDeclaredMethod("dequeue", null);
for (int i = 0 ; i < calls.length ; i++)
{
if (calls[i].equalsIgnoreCase("enqueue"))
calledMethod1.invoke(calledClass.newInstance(), param[i], param2[i]);
else if (calls[i].equalsIgnoreCase("dequeue"))
calledMethod2.invoke(calledClass.newInstance())
}
} catch (ClassNotFoundException e)
{
e.printStackTrace();
} catch (NoSuchMethodException e)
{
e.printStackTrace();
} catch (SecurityException e)
{
e.printStackTrace();
} catch (IllegalAccessException e)
{
e.printStackTrace();
} catch (IllegalArgumentException e)
{
e.printStackTrace();
} catch (InvocationTargetException e)
{
e.printStackTrace();
}
}
}
I already tested this solution and it works really very smooth, but please if anyone has a better solution, you will be more than welcome.
I will finalize the code and make it something like a tool, and I will post it soon, in order to make everybody's life easier debugging the online judges test cases.
Update:
You can do the same for the static methods, just remove .newInstance() from calledMethod1.invoke(calledClass.newInstance(), param[i], param2[i]); to something like calledMethod1.invoke(calledClass, param[i], param2[i]);
Two questions regarding the MethodHandle class:
Is it true that every call to invokeExact() requires type casting of the return value (except for target methods that return void or Object) ?
It seems that a MethodHandle can only be bound once to a receiver. Given an arbitrary MethodHandle instance, is there any way to determine whether it has already been bound and if so, to what type?
public static void main(String[] args) throws Throwable {
MethodHandles.Lookup lookup = MethodHandles.publicLookup();
MethodHandle handle = lookup.bind(new Object(), "toString", MethodType.methodType(String.class));
String s = (String) handle.invokeExact();
System.out.println(s);
try {
handle.invokeExact();
}
catch (WrongMethodTypeException e) {
System.out.println(e);
}
try {
handle.bindTo(new Object());
}
catch (IllegalArgumentException e) {
System.out.println(e);
}
}
You can call bindTo multiple times, but you should not. The implementation assumes you want to set the receiver, if you start using this to also set arguments you produce a more complicated handle, that is more difficult to compile into lambda forms and then potentially less efficient. I advise using MethodHandles#insertArguments instead
I've got this method I'm working on (I think that's the name) and it essentially tries to match a part of a string and then return the proceeding part of the string - that part I've got, easy stuff. The method is of type String.
When my method fails to find the pattern in the string I want it to return an empty string. I also want to send something along with the empty string to go "hey, I didn't find your key" but I want this to be optional.
This is essentially what I want the method to do:
public static String getKey(String key) throws KeyNotFoundException {
if (key.equals("something")) {
return "great";
} else {
throw new KeyNotFoundException();
return "";
}
}
But the problem with this code is that the return ""; is obviously unreachable due to throw new KeyNotFoundException();.
If I was going to call this method I'd have to use the try {} catch(KeyNotFoundException knf) {} block. It's this block that I want to make optional however.
If I choose to be oblivious to the fact the key was not found (e.g. don't use try catch) then I just want to be given the empty string on return.
But I also want to be able to surround it with a try-catch block if I need to know whether the key was found for my operation to complete correctly.
I think I'm going about this the wrong way but I can't seem to figure out an alternative (new to Java), could anyone shred some light on this please?
The usual way to do this would be to write two methods, one which returns a default value, and one which throws an exception. You can have one of these call the other, to avoid duplication:
public static String getKey(String key) throws KeyNotFoundException {
String value = getOptionalKey(key);
if (value.equals("")) throw new KeyNotFoundException(key);
return value;
}
public static String getOptionalKey(String key) {
if (key.equals("something")) {
return "great";
} else {
return "";
}
}
The caller can then choose which one to call, based on their needs:
String value = getOptionalKey("uma"); // oblivious
try {
String value = getKey("uma"); // cognisant
}
catch (KeyNotFoundException e) {
// panic
}
You should either use return values or exceptions to denote an error condition, but not both.
Generally, if you anticipate that something can go wrong, use a return value, and if the error is exceptional, throw an exception (as the name suggests).
By definition, an exception disrupts the normal program flow. The exception "bubbles up" until someone catches it or the thread terminates.
You can't do exactly what you're trying, but you have a couple options. You could write a "safe" version of the method that returns a default value if the key isn't found, like you're trying to do, and have a separate method that will throw the exception if the key isn't found.
Another option, if you've defined KeyNotFoundException yourself, would be to derive from RuntimeException instead of simply Exception. Then, you could remove the throws declaration from your method signature and not publish the fact that the method could throw an exception.
You can't, however, throw an exception from the method AND return a value from the method.
Another way you could deal with optional return values is to use Java 8's Optional class, and let the caller decide what to do when the value is not present:
public static Optional<String> getOptionalKey(String key) {
if (key.equals("something")) {
return Optional.of("great");
} else {
return Optional.empty();
}
}
You could combine it with the multiple methods approach discussed in other answers:
public static String getKey(String key) throws KeyNotFoundException {
return getOptionalKey(key).orElseThrow(() -> new KeyNotFoundException(key));
}
What about if you create your own Exception (extend Exception) which will have a constructor that takes a String or whatever you want to send to it (like error code or statement)?
Then you can have a getter method within your Custom Exception that will be used to "get" whatever the error message was.
nope. a method can only end with returning a value/end or return; if it is void OR throw an exception.
From what I understand of what you want to achieve, you could use a void returning method and provide a reference of a special object in argument. you would then set a field of this object to the result you want to 'return' and throw the exception.
Something like
class final ResultHoder {
String result;
public void setResult(String result) {
this.result = result;
}
public String getResult() {
return this.result;
}
}
public static void getKey(String key, ResultHolder result) throws KeyNotFoundException {
if (key.equals("something")) {
result.setResult("great");
return;
} else {
result.setResult("");
throw new KeyNotFoundException();
}
}