In Java, when for example you say string1.compareTo(string2), how is the compareTo method accessing the string1. I see the method takes in the second string but how does it compare it to the first if it is not getting passed along?
compareTo() is a member function of Class String, this means that for invoking this function you need an Object of Type String. So when you say string1.compareTo(string2) , this means that you are invoking compareTo() function on the String object 'string1' and passing 'string2' as the argument.
I think this little 'illustration' could help you
Class String {
public int CompareTo(String string2)
{
if (this==string2) return 1; //The == is completely wrong here but it gives you an idea on how it works
else return 0;
}
}
When you call string1.CompareTo(string2); in the method, this will reference the object itself, so here it references string1
Related
I have added three methods with parameters:
public static void doSomething(Object obj) {
System.out.println("Object called");
}
public static void doSomething(char[] obj) {
System.out.println("Array called");
}
public static void doSomething(Integer obj) {
System.out.println("Integer called");
}
When I am calling doSomething(null) , then compiler throws error as ambiguous methods. So is the issue because Integer and char[] methods or Integer and Object methods?
Java will always try to use the most specific applicable version of a method that's available (see JLS ยง15.12.2).
Object, char[] and Integer can all take null as a valid value. Therefore all 3 version are applicable, so Java will have to find the most specific one.
Since Object is the super-type of char[], the array version is more specific than the Object-version. So if only those two methods exist, the char[] version will be chosen.
When both the char[] and Integer versions are available, then both of them are more specific than Object but none is more specific than the other, so Java can't decide which one to call. In this case you'll have to explicitly mention which one you want to call by casting the argument to the appropriate type.
Note that in practice this problem occurs far more seldom than one might think. The reason for this is that it only happens when you're explicitly calling a method with null or with a variable of a rather un-specific type (such as Object).
On the contrary, the following invocation would be perfectly unambiguous:
char[] x = null;
doSomething(x);
Although you're still passing the value null, Java knows exactly which method to call, since it will take the type of the variable into account.
Each pair of these three methods is ambiguous by itself when called with a null argument. Because each parameter type is a reference type.
The following are the three ways to call one specific method of yours with null.
doSomething( (Object) null);
doSomething( (Integer) null);
doSomething( (char[]) null);
May I suggest to remove this ambiguity if you actually plan to call these methods with null arguments. Such a design invites errors in the future.
null is a valid value for any of the three types; so the compiler cannot decide which function to use. Use something like doSomething((Object)null) or doSomething((Integer)null) instead.
Every class in Java extends Object class.Even Integer class also extends Object. Hence both Object and Integer are considered as Object instance. So when you pass null as a parameter than compiler gets confused that which object method to call i.e. With parameter Object or parameter Integer since they both are object and their reference can be null. But the primitives in java does not extends Object.
I Have tried this and when there is exactly one pair of overloaded method and one of them has a parameter type Object then the compiler will always select the method with more specific type. But when there is more than one specific type, then the compiler throws an ambiguous method error.
Since this is a compile time event, this can only happen when one intentionally passes null to this method. If this is done intentionally then it is better to overload this method again with no parameter or create another method altogether.
class Sample{
public static void main (String[] args) {
Sample s = new Sample();
s.printVal(null);
}
public static void printVal(Object i){
System.out.println("obj called "+i);
}
public static void printVal(Integer i){
System.out.println("Int called "+i);
}
}
The output is Int called null and so ambiguity is with char[] and Integer
there is an ambiguity because of doSomething(char[] obj) and doSomething(Integer obj).
char[] and Integer both are the same superior for null that's why they are ambiguous.
I am new to the concepts of oop and therefore what I write have may have bad assumptions. Please correct me where appropriate.
In some code I saw a function takes in an argument in the form of int number. Then, in the function the following line is written outputString = Integer.toString( number );
I interpreted this as go the the class Integer, find a method called toString() and feed this the int called number and set the output of that to outputString. Since the syntax is class.method(arg) I assumed that toString() is a static function.
I wanted to test if it was static. I rewrote the code with the argument as Integer number and then did outputString = number.toString(); and it worked. This has the form obj.method(arg) which I had assumed would only work for non static methods.
I am unsure what conclusion to draw from this or if I have made a wrong assumption. Thanks.
If you're talking about the class Integer, it has two methods toString, one static and the other one is not static.
Integer a = 5;
a.toString() // Is valid
Integer.toString(5); // Also is valid
There are 3 methods in java.lang.Integer class.
public static String toString(int i);
public static String toString(int i, int radix);
public String toString();
In your first case, you have used the 1st one ( a static method).
In your second case, you have used the 3rd one ( a non-static method).
I think you should know more information about inheritance in java. All classes extend Object class, that is why all classes have non-static toString() method and can override it. Class Integer have also static toString(int number) that returns String representation of int.
The Integer class has 2 methods as below;
public static String toString(int i) {
if (i == Integer.MIN_VALUE)
return "-2147483648";
int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
char[] buf = new char[size];
getChars(i, size, buf);
return new String(buf, true);
}
AND
public String toString() {
return toString(value);
}
Both the methods are self explanatory. To Note second method calls the first one.
Integer.toString(1); // Calls method 1
Integer one = 1;
one.toString(); // Calls method 2
You may also want to lookup the Object's toString() method, which by the way gets inherited in every objects in java. This method is not static. The Integer's toString(int) method is only specific to the Integer class. This method is static (does not work on objects, but only on the Integer class). You will also want to check out the concepts of "method overriding", "method overloading" and "polymorphism". Here's a page containing almost exactly your question: https://www.geeksforgeeks.org/can-we-overload-or-override-static-methods-in-java/
This question already has answers here:
Can someone explain a void return type in Java?
(5 answers)
Closed 6 years ago.
I'm confused about "void",
as it pertains to methods.
I don't know what the distinction between two methods is when one has "void" and another doesn't.
For example, if I do:
Public meth (int amount)
{
amount = initial * interest;
return amount;
}
( not sure if it was right, or even valid, to take the name "amount" and name it the same thing as my formal parameter, but what makes sense here is that you're performing a calculation and returning the result)
Then, if I did something like:
Public void Testing (int array[])
{
//code that would modify the internals of an array
}
Would the second one have no "return" because it's more of a general method, that can be applied to any integer array, while the first one is about doing work on specific variables?
Would also appreciate one or two more examples of when I would or wouldn't be using "void" and "return".
One other thing that seems to confuse me is calling methods.
I know sometimes I'll do something like, for example, using the Testing method above,
Testing(ArrayName);
Other times, it will be like:
NameOfWhateverImApplyingMethodTo.MethodName();
And then there are times when things will be done properly by:
Thing1.MethodName(Thing2);
Which circumstances would I switch the syntax for method calls like this?
Java is case sensitive, so the modifier Public is invalid, use public
You can't define a method as public methodName(int a), only a constructor has this signature, a method must be public void methodName(<signature>) for methods that don't return anything or public <return type> methodName(<signature>) for methods that do.
Void basically means that the method will not return anything.
If you did
String name= "tim";
public void getName(){
return name;
}
This would result in an error, because the getName method is returning a string object called name, but the method declaration is saying I am returning nothing - because it is void.
Instead the method should be :
String name = "tim";
public String getName(){
return name;
}
Now when the method getName() is called it will return a string object "name" with "tim" inside of it :)
You might have void for a set method. So for example
String name = "tim";
public void setName(String newName){
this.name = newName;
}
When this method is called you would use setName("Andy"); and it would set the value of the name variable to be "Andy". Nothing is returned in this method, because it is setting something, but there is no need to send anything back, so we use void on the method declaration.
Hope this helps.
The method that has void as return type does not return anything. For example you want to set a field firstName in your class. You will write a setting method like
public void setFirstName(String n) {
this.firstName = n;
}
As you can see you are just setting a class variable and does not require to return anything.
If you dont use void then you have to provide a return type for method. Like if you wish to write a getter for above variable as:
public String getFirstName() {
return this.firstName;
}
Once you provide a return type, you will have to return a value of that type otherwise your code will not compile.
Calling a method can be done based on where you are calling it from and what modifier is used:
If you are calling the method from the same class then you can simply write firstName = getFirstName()
If you are calling the method from another class then you require object of method's class as qualifier like personObject.getFirstName()
If you are calling a static method then you require class name as qualifier like Person.getFirstName();
Return type is what you get out of it. When you call it, what are you hoping to get back? For instance, if the method gets the average of two numbers, then you're expecting a number back, so the return type will be a number type, like "int" (integer).
You can see what it should be using that logic or by looking in the method for the word return - what comes after return is what is returned, and its type should be declared in the method (e.g. if it says "return 4;" it's returning an int, and should be e.g. public int getFour()
You also asked about e.g. testing() vs testing(word)
I remember having the same difficulty. The distinction between the two also relates to the method declaration line. I'll illustrate.
public String testing(){
return "a word";
}
Calling this method by doing "System.out.println(testing());" should print "a word". Calling this method by doing "System.out.println(testing("a word"));" will give you an issue - this is because when you call testing, it looks at the appropriate method: one in the right class, with the right return type and with the right arguments/parameters. If you're calling testing("a word"), that means you're using a String as an argument (because "a word" is a string), and so it tries to use the testing(String aString) method - which doesn't exist.
So you use empty brackets when the method takes no input, and you put stuff in brackets when the method expects stuff. This should be less confusing than it sounds, because it's usually logical - if you want to call a method that returns an average, you need to ask yourself "Average of what?" You'd probably need to supply it with the values you want the average of.
Moving on: (a) testing() versus(b) AClass.testing() versus(c) aclass.testing() -
In (a), there's no class specified. Therefore, if you call it from that class, Java can guess which class: this one, and it'll work. From any other class, it won't know what you're talking about, and might even insult you.
In (b), you're specifying a class in general - therefore it'll know what class to find it in - and it'll work if it's a "static method". *[see bottom]
In (c), you're specifying an instance of AClass you want to run "testing()" on*.
For instance, imagine you've created a class called Business. You make a hundred Business objects by specifying for each a name, number, address.
e.g.
Business b = new Business(name, number, address);
Then in the Business class you have a method "getName()". This method takes no argument - you could see that the brackets are empty - so if, from another class, you call "Business.getName()", how could it know which name you want? You've just made a hundred businesses!
It simply can't. Therefore, for such a method, you'd call "b.getName()" (b being the Business we created above) and it would get the name for this instance of a Business - namely, b.
I'm happy to help, so if you're confused about any particular parts of what I just wrote please let me know and I'll try to elaborate!
edit: A bit on static methods:
Static methods don't belong to an instance of the class. getName(), for example, would get the name of this Business - ie, this instance of the Business class. But let's say that in the Business class you made a method that took the first letter of each word in a String and transformed it to uppercase - like if you wanted to make the business names look more professional when you printed them out.
public static String stringToUpperCase(String aString){
aString = aString.substring(0, 1).toUpperCase() + aString.substring(1);
return aString;
}
And to use that, you change the getName() method from:
public String getName(){
return name;
}
to
public String getName(){
return stringToUpperCase(name);
}
The new method is used here to make the name have an uppercase first letter - but that is the extent of its involvement with the Business class. You notice it doesn't ask for information about the name, address, or number for a particular business. It just takes a string you give it, does something to it, and gives it back. It doesn't matter whether you have no Businesses or a hundred.
To call this method, you'd use:
System.out.println(Business.stringToUpperCase("hello"));
This would print Hello.
If it were not a static method, you'd have to make a new Business first:
Business b = new Business("aName", "aNumber", "anAddress");
System.out.println(b.stringToUpperCase("hello"));
And if the method did need access to more Business-instance information (like a business's name number or address) it wouldn't be able to be an instance variable.
The first example, a method without a return type at all, is a constructor; used when an instance is created with new. However, you can't return a value from a constructor. Something like,
this.amount = initial * interest; // return amount;
Sets the field amount to initial * interest.
I know some basics of java language.
But I don't know some statements like this:
method1().method2().method3()
Two or three methods separated whit dots operator! I cannot understand it.
What does it mean? How can I use them? Do they process from left to right or reverse?
Does they return special values or not?
How can I understand I should some methods separate whit dot?
How can I create methods like this?
I will gave you a little example.
method1().method2().method3();
getYear().toString().trim();
first execute get year() which returns a Integer:
1995.toString().trim();
secound execute toString() method of integer class which returns an string:
"1995".trim();
at least the compiler would execute trim() method of string class.
the first method return a number then you use toString() method on this number and format it to a string. this will return a string and then you can use the trim() method of string class to trim() the string. you are executed the next method after you get the return from the method in front of.
That is chaining of method calls. THe object returned by method1() will call method2()
As an example,
public static String methodToReturnString() {
return "someString";
}
You call this using String subString = methodToReturnString().toLowerCase().substring(3);
This returns a String estring.
This is similar to the code as follows.
String s1 = methodToReturnString();
String s2 = s1.toLowerCase();
String s3 = s2.substring(3);
System.out.println(s3);
As for generating this s3 variable, we needed to store the return values of method in some variables which is not needed. Using method chaining, we have avoided variables s1, s2 here.
method1 returns object, which has method2 and then you can call method2, which returns object that has method3 and you call it.
Your statement will be interpreted as follows:
Invoke method1(). The return value will be some object.
Invoke method2() on the object returned by method1(). This method too must have a return value.
Invoke method3() on the object returned by method2().
You can rewrite this as:
SomeType value1 = method1();
SomeOtherType value2 = value1.method2();
value2.method3();
See... For example we might have
String s= "abcde";
String str = s.trim().subString(2);
1 --> trim() is called on "s".
2 --> subString() is called on the result of s.trim()
Method1 returns object1, which has method2 which returns object2, which has method3.
Object1 and object2 and current object can be identical, which is used in builder pattern.
Something like:
Student {
Semester lastFinishedSemester();
}
Semester {
Courses registeredCourses();
}
Courses {
void printCoursesAndGrades();
}
now if you are in one of student methods, you can call:
lastFinishedSemester().registeredCourses().printCoursesAndGrades();
obj.method1().method2().method3()
equals to
( ( obj.method1() ).method2() ).method3()
Important:
method1() must return an object that has method2()
method2() must return an object that has method3()
Source: Yosi Hendarsjah's answer in https://coderanch.com/t/398558/java/method-chaining
I am creating a method called swapElements(). It takes an array of integers, and two integer indexes. The method should swap the values of the array elements with the specified indexes.
public class{
int swapElements(int[] number, int value1, int value2){
int temp = number[value1];
number[value1] = number[value2];
number[value2] = temp;
}
}
As you have presented it, this method does not need to return anything, and should probably be declared void. However, if there is a specific contract it needs to fulfill then you should return whatever the interface definition says it should return.
There are four things wrong with your code.
The thing you're asking about: use return number;, because you want to return the array with swapped elements.
Make the method return an int[] (like int[] swapElements), not an int.
Your class has no name. You need to add a name, like public class IntArraySwapper { ....
Your method should be static. Without using that keyword, you must call it on an instance, like new IntArraySwapper().swapElements(...). Since this method has nothing to do with class instances, simply make it static (static int[] swapElements) so that you can call it like IntArraySwapper.swapElements(...).
Note that the method will also modify the original array, so techinically you don't need to return anything. If you want, you could just make it a void method and use the old array.
you can just make it return void.
or maybe a boolean to indicate that the sawp happened, with no errors.
like index out of range error.
In such cases the return type is not strictly required. So, you should return void. But if you indeed want to return something, consider returning boolean to specify if the swap happened or not. More precisely you can include the swap code into try catch block which returns True if the swap happened without any error and False otherwise.