I'm trying to find a way to remove a method parameter when a certain condition is met. If the condition is met - then the parameter should be taken away from the method - but if the condition is not met - the parameter should be added back again to that method. Is there any way to do this in java - I know overloaded methods can do this - but how can a method remove its parameters and add them back again is my question.
if(condition == true) {
//remove the parameter from the method because it is not needed
} else {
//add the parameter back again to the method so the code below can use it
}
/*
code which uses the parameter again...
*/
Thank you so much for helping - hope this was not too confusing
Java doesn't support changing method signatures during Runtime. You could instead just overload the same method, with 2 signatures like so:
public void method(int param1, int param2, int optional) {}
public void method(int param1, int param2) {
method(param1, param2, 'value, that is optional, but not necessary currently');
}
The changing of Signatures is not possible, because it would break everything, that accesses the method using its originial signature.
Related
This question already has answers here:
When I need to use Optional.orElseGet() over Optional.orElse()
(3 answers)
Closed 4 years ago.
The below code prints:
should Not have called
hello world
Why is orElse getting executed even when we have an Optional that contains a value?
public static void main(String[] args){
String o = Optional.ofNullable("world").map(str -> "hello" + str).orElse(dontCallMe());
System.out.println(o);
}
private static String dontCallMe() {
System.out.println("should Not have called");
return "why god why";
}
The orElse method looks like this:
public T orElse(T other) {
return value != null ? value : other;
}
There isn't any complex logic here.
As with any method, it will do the following:
Get the actual values of all parameters passed to the method (which includes calling any methods in those parameters).
Pass those parameters to the method.
Execute the method.
The fact that we don't actually care about the value of the parameter doesn't change this process (this is just the way the language has been designed, for better or worse).
If you're looking to not call the method in the parameter, you're probably looking for Optional.orElseGet.
This:
public static void main(String[] args){
String o = Optional.ofNullable("world").map(str -> "hello" + str)
.orElseGet(() -> dontCallMe());
System.out.println(o);
}
private static String dontCallMe() {
System.out.println("should not have called");
return "why oh why";
}
Outputs only:
helloworld
The difference here is that the thing (Supplier) we're passing to the method will stay () -> dontCallMe(), it does not become () -> "why oh why" - only when you call get does it actually evaluate what's going on there and does dontCallMe actually get called.
Please, can somebody explain why orElse is getting executed event
after map will get executed for final result.
With the orElse method regardless if the wrapped value is present or not, the default object is created.
Hence when you call the function dontCallMe() in the orElse to return the string value; "should Not have called" will be printed to the console.
Using orElseGet instead of orElse would provide the result you expected although you should only use this method either when the default value is computationally expensive to create or you want to be sure this is done if and only if the value is absent (empty optional) in which case it's a necessity.
As an aside, there's no need to use Optional.ofNullable here, the Optional.of method is more appropriate as the former should only be used if the argument can be null and the latter only if the argument cannot be null.
As a reading, you can check out this good post on the baeldung site.
Guide To Java 8 Optional
For example, there is a method public void set_gender(String gender) {}, make sure only "male" or "female" is passed to this method without using enumeration.
Also, how to meet this demand when the method declaration is public void set_gender(String... params) {}?
If there's no such way to realize this, how could I give a warning in IDE when someone is passing a string that this method could not understand, just like how it works in Android Studio when I'm passing a value that is not a flag that defined inside a certain Class.
These are 4 ways I could think of:
Use pre-defined method without parameter:
public void setMale() { /* TODO: Implement */ }
public void setFemale() { /* TODO: Implement */ }
Keep setGender() but use boolean values as its parameter instead of plain String. true means it's male, false female (or the other way around):
public void setGender(boolean male) { /* TODO: Implement */ }
Keep setGender() while using String as its parameter, and throw an IllegalArgumentException if the supplied parameter does not comply with the scope:
public void setGender(String gender) {
if (!"male".equalsIgnoreCase(gender) && !"female".equalsIgnoreCase(gender)) {
throw new IllegalArgumentException("Bad parameter");
}
/* TODO: Implement */
}
Just use enums which, frankly, was designed with this exact use cases in mind. Or IntDef if you're really that worried about performance.
Oh, and as an addition, this question you asked:
If there's no such way to realize this, how could I give a warning in
IDE when someone is passing a string that this method could not
understand, just like how it works in Android Studio when I'm passing
a value that is not a flag that defined inside a certain Class.
They achieve this by using IntDef. ;)
There is StringDef annotation for such cases. You can mark parameter with it and then check it in runtime to verify.
well I'm wondering if it's possible to have a method where another method is passed as a parameter, so the first method can call the method passed in param?
Like for instance:
public void goToVisitManagementForm() throws ParseException {
if (isAuthenticated() && userTypeIs("Patient")) {
// I could have this whole block just moved to another method?
Panel newPanel = new Panel("Choose the details for your visit");
Component visitManagementForm = new VisitManagementForm(userData,
this);
newPanel.addComponent(visitManagementForm);
mainWindow.setMainPanel(newPanel);
} else {
authenticate();
}
}
If the code block would be moved to another method and it would be passed as a parameter to this method. How can I achieve that and is this a good practice? Because in this case I have the ifs that I always need to paste in...
What about other aspects of this?
This is called a higher-order function and you cannot do this in Java 7 or below. You can simulate passing functions to other functions through the use of an anonymous class that instantiates some interface the function expects, and then calling the function on that object.
For example, to pass a no-arg function:
interface Function {
void apply();
}
void takesAFunction(Function function) {
function.apply();
}
Then the following code snippet would do what you want:
Function myFunction = new Function() {
#Override
public void apply() {
// your code here.
}
};
takesAFunction(myFunction);
As a side note, reflection is extreme overkill for this type of problem.
You can pass methods as parameters using Java Reflection API.
First, you get a method object from a class:
Class c = MyClass.class;
Method[] methods = c.getMethods();
Method m = // choose the method you want
Then your function can take a Method object as a parameter:
public void aFunction(MyClass o, Method m);
And then inside that function you can invoke the method:
m.invoke(o);
This is a very simple example, where the method doesn't take any parameters. It's pretty easy to expand on this example and add the parameters as well.
Yes, but it is a very advanced procedure. You need to use the Method object. Here is the javadoc on Method:
here is the javadoc:
- http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/Method.html
If I am understanding your question correctly, you want to be able to pass a method as a parameter. There really is no 'smooth' way to do this in Java. In objective C, it is built right into the language, (#selector tag)
class WrongOverloading{
void something(String [] a){ .. }
Integer something(String... aaa){ return 1;}
}
Above code does not compile! Compiler says these are duplicate methods.
So using String array or String var-args exactly mean the same?
How are they implemented internally?
They are effectively the same, except the compiler will not accept an varargs unless its the last argument and it won't allow you to pass multiple arguments to an array.
public void methodA(int... ints, int a); // doesn't compile
public void methodA(int[] ints, int a); // compiles
public void methodB(int... ints); // compiles
public void methodC(int[] ints); // compiles
methodB(1); // compiles
methodB(1,2,3,4); // compiles
methodC(1); // doesn't compile
methodC(1,2,3,4); // doesn't compile
From this SO discussion
The underlying type of a variadic method function(Object... args) is
function(Object[] args). Sun added varargs in this manner to preserve
backwards compatibility.
So, as every other answer has said, yes, they're the same.
String... aaa is just like having String[] aaa.
I am assuming that the semicolon after the second function is a typo...
Yes, it's the same.
You can read this article:
It is still true that multiple arguments must be passed in an array, but the varargs feature automates and hides the process.
yes, they are the same because when you call method with elipsis (String...) it converts to String array.
The compiler behind the scenes actually converts your var args method to a method with an array input.
This is the reason why you can have a var args method overloaded with an array as input because after compilation both of them will be identical.
Yes, both are the same ...
http://docs.oracle.com/javase/1.5.0/docs/guide/language/varargs.html Just read this site, you will come to know
The [vararg] attribute specifies that the method takes a variable number of parameters. To accomplish this, the last parameter must be a safe array of VARIANT type that contains all the remaining parameters :
[vararg [, optional-attributes]] return-type function-name(
[optional-param-attributes] param-list,
SAFEARRAY(VARIANT) last-param-name);
The varargs syntax basically lets you specify that there are possible parameters, right? They can be there, or cannot be there. That's the purpose of the three dots. When you call the method, you can call it with or without those parameters. This was done to avoid having to pass arrays to the methods.
Have a look at this:
See When do you use varargs in Java?
final public class Main
{
private void show(int []a)
{
for(int i=0;i<a.length;i++)
{
System.out.print(a[i]+"\t");
}
}
private void show(Object...a)
{
for(int i=0;i<a.length;i++)
{
System.out.print(a[i]+"\t");
}
System.out.println("\nvarargs called");
}
public static void main(String... args)
{
int[]temp=new int[]{1,2,3,4};
Main main=new Main();
main.show(temp);
main.show(); //<-- This is possible.
}
}
It's for this reason, varargs is basically not recommended in overloading of methods.
System.out.printf(); is an example of varargs and defined as follows.
public PrintStream printf(String format, Object ... args)
{
return format(format, args);
}
format - A format string as described in Format string syntax
args - Arguments referenced by the format specifiers in the format string. If there are more arguments than format specifiers, the extra arguments are ignored. The number of arguments is variable and may be zero. The maximum number of arguments is limited by the maximum dimension of a Java array as defined by the Java Virtual Machine Specification. The behaviour on a null argument depends on the conversion.
while calling a method it doesnt care about the return type it will consider the method name , number of parameters and type of parameters and order of parameters .here you are specifying a method with same name same parameters .bcoz in case of var arg if we call method with 2 parameters same method will be executed , if we call method with 3 parameters it will call same method .
here , if we call something(String [] a) and something(String... aaa) same method will be called .bcoz we can replace array with var-arg then a confusion will be arise wich method should be called. then method ambiguity will occour . thats why its showing duplicate method.
here if we pass array to var - arg parameter method it will be executed.internally it converts var - args to single dimensional array.
Guys I know this question is silly but just to make sure:
Having in my class method:
boolean equals(Document d)
{
//do something
}
I'm overloading this method nor overriding right? I know that this or similiar question will be on upcoming egzam and would be stupid to not get points for such a simple mistake;
Based on the code provided, we can't tell for sure whether you're overloading or overriding it.
You are most likely overloading the equals(Object o) method.
class A {
void method() {..}
}
class B extends A {
// this is overriding
void method() {..}
}
And
// this is overloading
class A {
void method(boolean b) {..}
void method(String arg) {..}
void method(int arg) {..}
}
P.S. you are using a bracket convention that is not widely accepted on the java world. In Java it is more common to place opening the curly bracket on the same.
You are not even overloading, since the other method is called equals. But if you add that s, you will be overloading equals. Although, to be precise, we talk about overloading if two (or more) methods with the same name but different signature are defined in the same class. In your case, it is trickier, since your equals with its different signature partly hides the original equals. Which is usually a bad thing, because this almost always leads to hard to understand behaviour, thus subtle bugs. Whenever someone calls equals on an instance of your class, depending on the parameter type the call may go to a different implementation of the method.
class Document {
public boolean equals(Document d)
{
//do something
}
}
Document doc1 = new Document();
Document doc2 = new Document();
String string = new String();
doc1.equals(doc2); // calls Document.equals
doc1.equals(string); // calls Object.equals!
You would be overriding Object.equals if you defined your method with the exact same signature as the original, i.e.
public boolean equals(Object obj) ...
In this case, both of the above calls to equals correctly execute Document.equals.
From the code you posted it could be either. If equal is defined in a superclass with the same parameter declarations then you are overriding it. If there is already a method called equal, but with different parameter types, you are overloading it.
On a related note, if you are using Java 5 and above and your intent is to override then it is highly recommended to use the #Override annotation before the method definition to indicate your intention. The wrong usage of this annotation (i.e. when you want to override and are not doing so) would flag a compile error.
As of Java 6 you can use the #Override annotation while defining methods that are
declared in an interface the class in implementing.
Overloading: same method name, same parameter list, different classes
Overriding: same method name, different parameter list, same or different classes.
Class A {
bool Equals(Document d) {...}
bool Equals(A a) {...} // overloaded method
}
Class B extends A {
bool Equals(Document d) {...} // overridden method
bool Equals(B b) {...} // overloaded method
}
One thing to note, the return type does not matter, it's the name of the method and the parameter list that make all the difference.