can someone explain me how this is working ? i'm getting c as my output, it's my 3rd day on java . Thanx in advance
class adarsh
{
private void print( ){
System.out.println("a");
}
private void print(String str){
System.out.println("b");
}
private void print(int x){
System.out.println("c");
}
public static void main(String[] args){
adarsh object = new adarsh();
object.print(12);
}
}
Then a class has multiple methods with the same name and different parameter lists, it's called method overloading. print is an overloaded method in your class. When you use it, the method that gets used depends on the number and type of the arguments you use in the call: The best matching method is used. Because you used 12, which is an integer literal, it has the type int, so print(int) was called. If you'd used no argument, print() would have been called. If you'd used print("foo"), print(String) would have been called.
Side note: Please use the Java naming conventions, at least when asking for help (but it's best when not asking for help, too). Your class should be called Adarsh, not adarsh.
See Method overloading in Java. The method having the signature private void print(int x) was picked by the compiler, since you passed print an int.
What you have tried is an example of Method Overloading which allows different methods to have the same name, but different signatures where the signature can differ by the number of input parameters or type of input parameters or both.
In your code, object.print(12) matches the method based on type of argument.
You call the method by passing an int 12 so the method with int as an argument is invoked and it prints c
Use of Overloading
We don’t have to create and remember different names for functions doing the same thing. For example, in your code, if overloading was not supported by Java, you would have to create method names like print1, print2, print3 … etc.. though all methods do the same printing work. Thus improves readability of code.
And one more thing, Please use the Java Naming Conventions
Class names should be nouns, in mixed case with the first letter of each internal word capitalised.
Use whole words and must avoid acronyms and abbreviations.
Related
public class OverloadingTest extends Format{
public int add(String s1){
System.out.println("With String");
return 1;
}
public int add(Object a){
System.out.println("With Object");
return 1;
}
public static void main(String[] args) {
OverloadingTest overloadingTest = new OverloadingTest();
overloadingTest.add(null);
}
}
Why is the output of the program With String ?
I have tried reading JLS for 6th Version, but I still could not find the answer.
The only reason I could guess is that the closest match in Inheritance hierarchy is chosen.
So in this case it would take String as Object is its super class.
This answer is available in the question Method Overloading for NULL parameter:
Java will always try to use the most specific applicable version of a method that's available (see JLS §15.12.2).
So, as a result, String is used, because it's the most specific type available. If more than one subtype exists, then you will have to cast null to the appropriate type to designate which function you want to run.
This is spelled out in §15.12.2.5. Choosing the Most Specific Method:
If more than one member method is both accessible and applicable to a method invocation, it is necessary to choose one to provide the descriptor for the run-time method dispatch. The Java programming language uses the rule that the most specific method is chosen.
The informal intuition is that one method is more specific than another if any invocation handled by the first method could be passed on to the other one without a compile-time type error.
In your example, add(Object) can handle anything that add(String) can. This makes the latter more specific. It is therefore the one that gets chosen to handle null.
If more than one member method is both accessible and applicable to a method invocation ... The Java programming language uses the rule that the most specific method is chosen.
See The Java Language Specification
I have this following code and I need some clarification regarding the overloading concept.
class Overload{
static void print(Object o){
System.out.println("object");
}
static void print(String s){
System.out.println("string");
}
public static void main(String...args){
print("Hello");
}
}
when I execute this, the output is String. Eventhough object is the super class, why does it display string instead of object?
thanks in advance
The rule in this case is:
the more specific signature will apply
String is more specific than Object, that's why print(String) is used. For instance, try with print(null) in your main, you will see find out that such code will not even compile, since the compiler will have no way to distinguish whether null is a String or an Object
Check out Oracle Overloading Tutorial
There is called string print because you pass "Hello" which is String object.
String also extends regular Object but overloading calls also the most upper type.
Currently, this version of overloaded method executes:
static void print(String s){
System.out.println("string");
}
Since you are calling like this:
print("Hello");
Data conversions happen only if and only if correct version of match is not found. And exact match is found for compiler.
First JVM sees for the print(String), if not found it searches for print() with argument of superclass of String. If still not found, then super-class of super-class of String. And this algorithm continues until there is print(Object). Or reporting an error
Because when there is an exact match, during overloaded functions, JVM will not consider generalization. i.e it will look for the best fit to match the argument type. In this case "Hello" is an exact match to String type. Since String fits better in String than in Object. Hence it will not consider
static void print(Object o)
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Method Overloading for NULL parameter
In the code below the output is
String
and if I remove the method with the parameter of type String then the output is
Object
I know how overloading of methods acts when the parameter types don't match exactly but I can not understand how null can be treated as an Object and/or a String parameter.
What is the explanation for this?
class C {
static void m1(Object x) {
System.out.print("Object");
}
static void m1(String x) {
System.out.print("String");
}
public static void main(String[] args) {
m1(null);
}
}
It always uses the most specific method according to the Java specs, section 15.12.2.5.
The intro is reasonably specific about it:
If more than one member method is both accessible and applicable to a method invocation, it is necessary to choose one to provide the descriptor for the run-time method dispatch. The Java programming language uses the rule that the most specific method is chosen.
The informal intuition is that one method is more specific than another if any invocation handled by the first method could be passed on to the other one without a compile-time type error.
Generally speaking, and at least for code readability, it's always best to try to be as explicit as possible. You could cast your null into the type that matches the signature you want to call. But that's definitely a questionable practice. It assumes everyone knows this rule and makes the code more difficult to read.
But it's a good academic question, so I +1 your question.
When multiple overloads match a signature, Java picks the most specific method from among them.
The value of null matches both Object and String, but String is a subclass of Object, so String is picked. If you add another overload with a sibling of String in the class hierarchy, you'd get a compile error.\
// DOES NOT COMPILE
class C {
static void m1(Object x) {
System.out.print("Object");
}
static void m1(String x) {
System.out.print("String");
}
static void m1(Integer x) {
System.out.print("Integer");
}
public static void main(String[] args) {
m1(null);
}
}
Here is a link to a post that discusses your code example at some length.
If you need to force the call of a aprticular overloaded method when passing null as parameter, you have to cast it, like this:
m1((String)null);
By doing this, you make sure you're calling the correct overloaded version of the method.
You have to set the type of null to tell Java what function you want to call.
So you do: m1((Object) null); to call the implementation with the Object parameter and you do m1((String) null); to call the other one.
1. As String is also an object the JVM got confused to call which method at runtime.
2. If you want to specify which method to call at runtime, you can do this by explicit casting
eg:
m1((String)null);
Note that all the code is a simplified example in order to only communicate the core ideas of my question. It should all compile and run though, after slight editing.
I have several classes which all implement a common interface.
public interface Inter{}
public class Inter1 implements Inter{}
public class Inter2 implements Inter{}
In a separate class I have a list of type Inter, which I use to store and remove Inter1 and Inter2 types, based on user input.
java.util.ArrayList<Inter> inters = new java.util.ArrayList<Inter>();
I also have a family of overloaded methods, which deal with how each implementation interacts with each other, along with a default implementation for 2 "Inter"s.
void doSomething(Inter in1, Inter in2){
System.out.println("Inter/Inter");
}
void doSomething(Inter1 in1, Inter1 in2){
System.out.println("Inter1/Inter11");
}
void doSomething(Inter2 in1, Inter1 in2){
System.out.println("Inter2/Inter1");
}
The methods are periodically called like so:
for(int i = 0; i < inters.size() - 1; i++){
for(int o = i+1; o < inters.size(); o++){
Inter in1 = inters.get(i); Inter in2 = inters.get(o);
doSomething(in1.getClass().cast(in1), in2.getClass().cast(in2));
System.out.println("Class 1: " + in1.getClass().getName());
System.out.println("Class 2: " + in2.getClass().getName());
}
}
An example output from this is:
Inter/Inter
Class 1: Inter
Class 2: Inter
Inter/Inter
Class 1: Inter
Class 2: Inter1
Inter/Inter
Class 1: Inter1
Class 2: Inter1
Looking at the output, it is clear that doSomething(Inter in1, Inter in2) is called, even in cases when other methods should be called. Interestingly, the class names outputted are the correct ones.
Why does java have static method overloading when the class types are determined at runtime using reflection?
Is there any way to get Java to do this? I know I can use reflection and Class.getMethod() and method.invoke() to get the results I want, but it would be so much neater to do so with casting.
I realize that questions about similar concepts have been asked before, but while all of the answers were informative, none satisfied me.
Double dispatch looked like it would work, but that would mean reworking a lot of code, since I use this type of thing often.
It looks to me like we're talking about what's going on with:
doSomething(in1.getClass().cast(in1), in2.getClass().cast(in2));
Based on your surprise that the type that is being output is always Inter, it seems you're a little confused on what's going on here. In particular, you seem to think that in1.getClass().cast(in1) and in2.getClass().cast(in2) should be forcing a different overload because of their differing runtime type. However, this is wrong.
Method overload resolution happens statically. This means that it happens based on the declared types of the two arguments to the method. Since both in1 and in2 are both declared as Inter, the method chosen is obviously void doSomething(Inter in1, Inter in2).
The takeaway here is that in1 is declared as an Inter. This means that in1.getClass() is essentially the same as Inter.class for the purposes of static analysis -- getClass simply returns a Class<? extends Inter>. Therefore, the casts are useless, and you're only ever going to get the first overload.
The Java Language Specification (JLS) in section 15.12 Method Invocation Expression explains in detail the process that the compiler follows to choose the right method to invoke.
There, you will notice that this is a compile-time task. The JLS says in subsection 15.12.2:
This step uses the name of the method and the types of the argument expressions
to locate methods that are both accessible and applicable
There may be more than one such method, in which case the most specific one is chosen.
In your case, this means that since you are passing two objects of type Integer, the most specific method is the one that receives exactly that.
To verify the compile-time nature of this, you can do the following test.
Declare a class like this and compile it.
public class ChooseMethod {
public void doSomething(Number n){
System.out.println("Number");
}
}
Declare a second class that invokes a method of the first one and compile it.
public class MethodChooser {
public static void main(String[] args) {
ChooseMethod m = new ChooseMethod();
m.doSomething(10);
}
}
If you invoke the main, the output says Number.
Now, add a second more specific method to the ChooseMethod class, and recompile it (but do not recompile the other class).
public void doSomething(Integer i) {
System.out.println("Integer");
}
If you run the main again, the output is still Number.
Basically, because it was decided at compile time. If you recompile the MethodChooser class (the one with the main), and run the program again, the output will be Integer.
As such, if you want to force the selection of one of the overloaded methods, the type of the arguments must correspond with the type of the parameters at compile time, and not only at run time as you seem to expect in this exercise.
Overriding a method can be prevented by using the keyword final, likewise how to prevent overloading?
You can't. Because it's almost pointless.
If you want to overload the method handle(..) but you are disallowed to, you'd create doHandle(..) instead.
Which overloaded method is used is determined at compile time (in contrast to overridden methods, which are determined at runtime). So the point of overloading is sharing a common name for common operations. Disallowing that is a matter of code-style, rather than anything else.
You can't do that in Java.
An overloaded method is basically just another method.
An attempt could look (something) like this
void yourMethod(String arg) { /* ... */ }
void yourMethod(String arg, Object... prevent) {
throw new IllegalArgumentException();
}
but it won't work since Java resolves overloading by looking at the "best match" or "most specific signature".
The method could still be overloaded with a
void yourMethod(String arg, String arg2) { /* ... */ }
which would be called when doing yourMethod("hello", "world").
Btw, why would you want to prevent overloading? Perhaps there is another way of doing what you want?
Err... what's the point in not allowing to Overload the method?
Protection from Overriding is allowed because it can be done by another programmer who is supposedly working on another part of code and his class is inherited from your class.
Overloading is done in the same class and is logically supposed to be done by a programmer who knows this code and is working on the same part of the code. So, if he knows this code (theoretically) and there is some inherent danger in overloading, then he should know this already because he knows the code.
That said, overloading cannot be stopped as others have already described.
Mark the class final and it can't be extended. That may defeat some other purpose though.
If you overload a method, you've created a method with the same name but different parameter types. In Java, a method is defined (partly) in terms of its parameters, and thus if two methods have the same name but different parameters, then they are apples and oranges, i.e., not the same. In short, you can't prevent someone from creating new methods in a class, which is essentially what you're asking for.
simple! don't call that overloaded method.
public class Test
{
public void m(int a)
{
*your definition*
}
public void m(float a)
{
*your definition*
}
}
public static void main(Strings [] args)
{
Test t=new Test();
t.m(5);
}
Overriding and Overloading are different techniques. Overloading is a way of declaring multiple methods with the same names but different parameter types or different no of parameters.
You can prevent a method from being overwritten by making it final, but you cannot prevent a method from being overloaded. Well technically you could make the class itself final, so that no methods at all can be added by creating a subclass but I don't think that's a good design.