I wonder that how it would help us in practice while writing code. In Java numeric wrapper class has overloaded static toString() method and return String representation of the parameter.
Is it common approach to use this methods?
Yes. You could use it whenever you want the String value of a number. Alternatively, you can use String.valueOf(int) note that the Javadoc refers to Integer.toString(int, int) where the second int is the radix.
No, this isn't common. It's simply a convenience method to use instead of having to box the argument into a wrapper object and then call toString on it. Since you can't define any more primitives, only objects, overriding the non-static toString is the way to go in your own code.
It is useful when you need to convert a variable of a primitive type to a String without creating a wrapper object.
Like this:
int a = 5;
String str = Integer.toString(a);
Related
According to Oracle Documentation, the String::compareToIgnoreCase is also a valid method reference, my question is that compareToIgnoreCase is not a static method, in other words, compareToIgnoreCase must be attached to a specific String instance. So how does JDK know which instance of String I refer when I use String::compareToIgnoreCase ?
Consider the following example using toUpperCase which is also an instance method.
It works in this case because the Stream item that is being handled is of the same type as the class of the method being invoked. So the item actually invokes the method directly.
So for
Stream.of("abcde").map(String::toUpperCase).forEach(System.out::println);
the String::toUpperCase call will be the same as "abcde".toUpperCase()
If you did something like this:
Stream.of("abcde").map(OtherClass::toUpperCase).forEach(System.out::println);
"abcde" is not a type of OtherClass so the OtherClass would need to look like the following for the stream to work.
class OtherClass {
public static String toUpperCase(String s) {
return s.toUpperCase();
}
}
String::compareToIgnoreCase is not used such as str1.compareToIgnoreCase(str2) would be.
It actually is used as a comparator.
E.g. you could compare it to
Arrays.sort(someIntegerArray, Collections.reverseOrder())
but in this case it would be
Arrays.sort(someStringArray, String::compareToIgnoreCase)
It is like there is an additional parameter, the actual instance, involved.
Example for String::compareToIgnoreCase:
ToIntBiFunction<String, String> func = String::compareToIgnoreCase;
int result = func.applyAsInt("ab", "cd"); // some negative number expected
We get a ToIntBiFunction - a two parameter function returning int - since the result is an int, the first parameter correspond to this of compareToIgnoreCase and the second function parameter is the parameter passed to compareToIgnoreCase.
maybe a bit easier:
ToIntFunction<String> f = String::length; // function accepting String, returning int
int length = f.applyAsInt("abc"); // 3
length does not accept any parameter, but the first argument of the function is used as the instance length is called on
The examples above are very abstract, just to show the types involved. The functions are mostly used directly in some method call, no need to use an intermediate variable
for example in Scanner we have
obj.next()
but we can call another method after next()
obj.next().charAt(0)
how can I make similar thing for example
obj.getName().toLowerCase()
What you have observed – with examples like obj.getName().toLowerCase() – is that when the return type of a method call is itself some other object, then you can immediately call a new method on that newly returned object.
Here's another example: String s = String.class.getName().toLowerCase();. This example could be rewritten like so:
Class<String> stringClass = String.class;
String name = stringClass.getName();
String s = name.toLowerCase();
Both of the one-line and multi-line version of this code result in a String object, referenced by s, which contains the value "java.lang.string".
Note that chaining method calls together is not possible if the return type isn't an object, such as an integer value. For example, here's a method call that results in a primitive long value, which isn't an object, so you can't call any methods on that result – that is, something like millis.hashCode() isn't possible.
long millis = System.currentTimeMillis();
To address your primary question finally: you can create this same behavior by creating methods that return objects instead of primitives (int, long, byte, etc.).
How is this legal
System.out.println("".valueOf(1121997));
And this is illegal
System.out.println(1.valueOf("1121997"));
"" is a string literal, and the java compiler makes sure that a String object will be automatically created for each string literal that you use in your program. So, since "" is an object, it has methods like valueOf().
On the other hand, 1 is an int literal, so there is no object created for it; it is just a primitive. Primitives do not have methods in java.
Because "" is a String. String Class has a valueOf method, so you can call it.
For your old question,
System.out.println( 1.valueOf("1121997"));
Here 1 is primitive integer value and not Integer Wrapper class. You can not call method on primitive data types.
For your updated Question,
System.out.println((Integer) 1.valueOf("1121997"));
Here you need to wrap (Integer)1 with additional ().
System.out.println(((Integer) 1).valueOf("1121997"));
Also valueOf() is a static method. It is not a good practice to call it with instance. You should call it directly with class name like
Integer.valueOf("1121997");
"" is a reference to a String Object, therefore has methods like length, valueOf, etc.
1 is an integer literal. It is a primitive data type, therefore you can't call methods on it.
I know this is silly question,but I am confused,and this is the best site where I find the perfect answers
There is toString method in object class,,whereas there is a toString method in each primitive wrapper classes also.one is with Static keyword,other is not.What is done there?overloading or overriding ?
In short,I mean to say,can we add static modifier to overridden classes? or tostring method in primitive wrapper classes are different to the toString method in object class
It took some time to understand your (confusing) question. I can suppose that you are speaking about primitive wrapper classes like Integer or Long that indeed have several overloaded static methods toString(). But each one of them has different signature.
The toString() method defined in java.lang.Object that can be overridden by subclasses does not accept arguments. The static methods toString that can be found in other classes (e.g. java.lang.Integer) accept arguments (e.g. public static String toString(int i), public static String toString(int i, int radix) etc)
I hope my interpretation of your question is correct.
The static (if you mean this as "class") method cannot hide the instance method. You will get the compile time error if you attempt this.
Each and Every Wrapper class overrides the toString() method
Let us say that I want to create a class MyString which is a wrapper for java.lang.String. I have added a new method called reverse.
public class MyString {
private String text=null;
public MyString(String foo){
text=foo;
}
public String reverse(){
// implementation omitted
return reversedString;
}
}
Now String is final. Therefore I cannot extend it. One way to have MyString support all methods that String supports is by providing wrapper method implementations such as the method toCharArray():
public char[] toCharArray(){
// redirect to String member field 'text'
return text.toCharArray();
}
Is there a way I can redirect method calls to the member field without actually having to code the wrapper implementation? Something similar to super?
No, this cannot be done directly.
You could define an interface containing all java.lang.String methods (plus your methods) and implement it with a dynamic proxy redirecting to the string implementation (with all the negative implications of dynamic proxies).
Probably you're better of with a type conversion new MyString(string).reverse() unfortunately Java does not have C#'s extension methods or Scala's implicit type conversions.
There are of course plenty of reverse implementations, for example from the apache commons library. It is implemented in a procedural style:
String reversed = StringUtils.reverse(string);
(I think your reverse method should return MyString not String so you can write: s.reverse().reverse()).
Not sure if I completely understand the question, but ultimately, if you want your MyString to have all the same methods as String, then at some level your class must also have all of the same methods defined. You can't really get around this.
You can probably come up with neat ways so that for every method you don't have to type return text.blah(), something more elegant than that; but I don't see any way how you could avoid having the method definitions in your MyString at all.
You can't do this as you have to write the methods to expose them for use. But, for example, you can use the Netbeans' "Create Delegates..." feature and you get all delegate methods with some mouse clicks.