Confusion in Function Overloading in JAVA [duplicate] - java

This question already has answers here:
Calling overloaded functions with "null" reference
(2 answers)
Closed 8 years ago.
I am new learner of Java. I am trying to understand the concept of passing argument in function and function overloading. I found few example on a java web site which where following code is given, my doubt is if null is passed to nh() then how "string" is displayed in output. Here is the code
public class CLI_APP
{
public static void main(String[] args)
{
jh(null);
}
public static void jh(String s)
{
System.out.print("String");
}
public static void jh(Object o)
{
System.out.print("Object");
}
}
In same code if below lines are added
public static void jh(Integer s)
{
System.out.print("Integer");
}
I got an compilation error of
"Method is ambiguous"
WHY this happen?

my doubt is if null is passed to nh() then how "string" is displayed in output
Overloaded methods are matched from bottom to top level of classes. Object class sits at the top level so it will be matched at the last. Having said that, null is first match to the String parameter method and a String can be null so this method is called.
If you also add the following method
public static void jh(Integer s)
to your code then jh(null) call introduces the ambiguity between Integer and String as both can be null.
Lean more here : Java Language Specification: Choosing the Most Specific Method

Integer and String both support null , so it generate ambiguity error at compile time,
Now, if you use int instead of Integer then it will work because int not support null.
public class testJava {
public static void main(String[] args)
{
jh(null);
}
public static void jh(String s)
{
System.out.print("String");
}
public static void jh(Object o)
{
System.out.print("Object");
}
public static void jh(int o)
{
System.out.print("Object int");
}
}

Java always use the most specific method. In your first example it will print "String" instead of "Object" because String is more specific than Object.
In your second example, java can´t choose if null is better for Integer or String. You should cast your call or use primitives to remove your ambiguity.
This would work:
public static void jh(int s)
{
System.out.print("Integer");
}
Also this would work:
jh((String) null);

Related

Passing a null function to java function as argument

I'm encountering problems understanding how function are passed to methods as parameters.
Searching on StackOverflow and StackExchange has brought me to a solution using java.util.Functions
public void someFunction(Functions <int[], int[]> myFunction);
(source: https://codereview.stackexchange.com/questions/186972/passing-a-generic-function-as-parameter)
Although this solution seems good to me, I'm facing problem when I need to pass a function which is intended to do nothing. For better understanding, consider the following example:
public class Example {
//do stuffs
myFunction(null);
}
public class Manager {
public void myFunction(Function<int[], void> funcToPass) { // Can't specify void as return value!
//do stuff
if(funcToPass != null) { // can't replicate such behaviour
funcToPass(someParams)
}
}
}
Can someone help me acquiring clear understanding on this topic? Thank you so much.
If you want to describe a function that does not return a value, you can use the Void type. This is a standard Java class, but is intended for use in this situation.
E.g.
Function<String, Void> stringPrinter = s -> {
System.out.println(s);
return null; // must return some value, null is acceptable since there is no Void instance
};
The return null; is important since, from the compiler's point of view, Void is just like any other class (e.g. String, Integer, etc). It doesn't know that it represents the absence of a value, whereas it does know that a function that returns void does not have a return value.
This means the compiler still expects some return statement in your code, just as if it were returning an Integer, and so you must return null;
EDIT:
You may find, however, if you are strictly dealing with functions with no returns, you are better suited to use a Consumer<T>. For example:
Consumer<String> stringPrinter = s -> System.out.println(s);
stringPrinter.accept("hello");
or, using a method reference:
Consumer<String> stringPrinter = System.out::println;
stringPrinter.accept("hello");
You can use Reflection API to pass a void method as a reference e.g.
import java.lang.reflect.Method;
public class Main {
public static void main(String[] args) throws Exception {
Class[] classParams = new Class[1];
classParams[0] = String.class;
Method method = Main.class.getMethod("hello", classParams);
Main obj = new Main();
System.out.println(new Main().getSum(obj, method, "world!", 10, 20));
}
public void hello(String msg) {
System.out.println("Hello " + msg);
}
int getSum(Object object, Method method, String msg, int x, int y) throws Exception {
Object[] objectParams = new Object[1];
objectParams[0] = msg;
method.invoke(object, objectParams);
return x + y;
}
}
Output:
Hello world!
30

Method overloading including parent and child class [duplicate]

This question already has answers here:
How is ambiguity in selecting from overloaded methods resolved in Java?
(5 answers)
Closed 4 years ago.
Why does the following code print "string"? Why is there no error because the method call is ambiguous?
class Mixer {
void print(String s) {
System.out.println("string");
}
void print(Object o) {
System.out.println("object");
}
public static void main(String[] args) {
Mixer m = new Mixer();
m.print(null);
}
}
Explanation
The String-method is chosen because it is the most specific of those types.
Since both methods would be accessible and applicable Java selects the most specific of both, this is described in the Java Language Specification in detail.
See JLS§15.12.2 which says:
There may be more than one such method, in which case the most specific one is chosen. The descriptor (signature plus return type) of the most specific method is one used at run time to perform the method dispatch.
JLS§15.12.2.5 lists all rules that are used to determine the most specific method.
Example
Take a look at the following methods:
public void foo(Object o) { ... }
public void foo(AbstractCollection<String> o) { ... }
public void foo(AbstractList<String> o) { ... }
public void foo(ArrayList<String> o) { ... }
With each method the specified type gets more specific, if you give an ArrayList or null it will thus first use the lowest method.

Can `greetSomeone("world")` be replaced by `greetSomeone(name)`? Is there any side effect to this change?

I'm new to Java and is trying to learn the concept of inner class. I saw the code below from Java tutorial Oracle. My question is, for
String name = "world";
#Override
public void greet() {
greetSomeone("world");
}
Can greetSomeone("world") be replaced by greetSomeone(name). The reason why I'm asking this question is because I have noticed if greetSomeone("world") is indeed replaced by greetSomeone(name), inside the public void greetSomeone() method, the passed "name" argument will be set to itself. I was just wondering if there are side effect to code like this?
public class HelloWorldAnonymousClasses {
interface HelloWorld {
public void greet();
public void greetSomeone(String someone);
}
public void sayHello() {
class EnglishGreeting implements HelloWorld {
String name = "world";
#Override
public void greet() {
greetSomeone("world");
}
#Override
public void greetSomeone(String someone) {
name = someone;
System.out.println("hello " + name);
}
}
HelloWorld eg1 = new EnglishGreeting();
eg1.greet();
}
public static void main(String[] args) {
HelloWorldAnonymousClasses myApp = new HelloWorldAnonymousClasses();
myApp.sayHello();
}
}
First of all why is that #Override annotation there?
You will use Override when you want to change the behaviour of the parent's methods. Your parent's methods have no behaviour as it is an interface. As a further note I guess that it will teach you that the signature of an overriden method must always match the one from the parent.
Secondly the design is kind of dodgy. It can be simplified.
Thirdly yes you can refer to the String object name as it is defined in that class and you can access the object's primitive just by calling 'name'. Why will you not get the reference printed when System.out? Because the String object handles that for you ensuring the toString will show you the primitive. When you do System.out.print(myObject); The console will show you the Object default or the overriden toString method.
So if you create an object and you do System.out.print(myObject) you will see the reference. If you override toString returning "test" you will see test.
Technically, name can be passed and name = name; is valid Java.
However, this is a horrible design and was probably used for demonstrative purposes only. Don't do this.

In Java, why Object class object in method parameter can not accept null [duplicate]

This question already has answers here:
How to do method overloading for null argument?
(7 answers)
Closed 8 years ago.
Please explain why i'm getting "Method with String param" in output.
And when i remove the comments from display(Test x) method, it says "Reference to display is ambiguous".
class Test
{
int a;
int b;
}
public class TestIt
{
public static void display(String x)
{
System.out.println("Method with String param");
}
public static void display(Object x)
{
System.out.println("Method with Object param");
}
/*
public static void display(Test x)
{
System.out.println("Method with Test param");
}
*/
public static void main(String args[])
{
display(null);
}
}
Because null is a valid value for Object and String. You can cast,
display((String) null);
Will output
Method with String param
or
display((Object) null);
for
Method with Object param
Because when figuring out which method to call, the compiler picks the most specific method it can find that matches the argument. Both display(String) and display(Object) match a call to display(null), but display(String) is more specific than display(Object), so the compiler uses that. When you uncomment the display(Test) version, though, the compiler can't make a choice because both display(String) and display(Test) are equally specific.
For all the gory details, see §15.12 of the JLS.

Is it possible to declare default argument in Java in String? [duplicate]

This question already has answers here:
Does Java support default parameter values?
(28 answers)
Closed 8 years ago.
Is it possible to use default argument in the method with String. The code is shown below:
public void test(String name="exampleText") {
}
The code above generate error. Is it possible to correct it?
No, the way you would normally do this is overload the method like so:
public void test()
{
test("exampleText");
}
public void test(String name)
{
}
No, it is not. However, the following is possible:
public void test() {
test("exampleText");
}
public void test(String name) {
//logic here
}

Categories

Resources