how two links are linked together in Java built-in libraries? - java

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.).

Related

Method Reference of Java

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

How is this static method called on a instance value wrong?

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.

Why the numeric wrapper class need to provide static toString() method?

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);

Declaring a method of class type?

I'd define myself as a beginner in Java, had it for just one semester and before that I had very little experience with programming whatsoever, virtually none with OOP.
Anyway, I'm going through a code and I found a method declared as a class type
public Polica stavi (Predmet p, int i)
throws GPolIndeks, GPolZauzeto, GPolTezina{
if(i<0 || i>=niz.length) throw new GPolIndeks (i);
if(niz[i] != null) throw new GPolZauzeto (i);
if(q + p.Q() > maxQ) throw new GPolTezina (p);
niz[i] = p;
q += p.Q();
return this;
}
Now the code is rather simple and almost I'm not stranger to it, except for the part where a method called "stavi" is declared. I've been thought there are two types of methods, those who return a value and those who don't, and this one does, but it is not declared as an any type regularly used (int, double, long...), it is declared with a class name, which in this case would be "Polica". This is the first time I'm coming to something like this and it works in a compiler, so my question would be, where can I read up on methods more in more detail, to better understand how this works.
Ok, I will explain some points for you. And its all about OOP
Polica is a class which will became an Object as soon as you create an instance of it
Polica polica = new Polica();
and methods can return any type of variables and also Objects
which means in your function you're expecting to return an Object Polica
public Polica stavi(){
Polica polica = new Polica();
return polica;
}
and this represents its self instance of its own so it would be really same with this
public Polica stavi(){
Polica polica = new Polica();
return this;
}
Well its nice that you have a great curiosity! here's a good tutorial for you.
http://docs.oracle.com/javase/tutorial/java/concepts/index.html
http://docs.oracle.com/javase/tutorial/java/javaOO/objects.html
Goodluck!
I would start with the Java Tutorials for Methods
In this example, the method is returning a reference to an object which in this case is the object you just invoked a method on. This is used for chaining and a class where is often using is StringBuilder eg.
String text = new StringBuilder().append("Hello, the time is ")
.append(new Date()).append("\n).toString();
As you can see, this works because each append method return this of the original StringBuilder.
In java or any other oops language the return type of a method can be any object type i.e it is not restricted to be of primitive type ( int, double...)
You should read this (language specification) for more details.
here you can find what you need. and answering to your question this method returns an object of type Polica.
Take a look at the documentation here
The return type does not have to be a int, long or double etc. It can be of an object you define yourself.
it is not declared as an any type regularly used (int, double, long...), it is declared with a class name
There is no difference between int, double, long, etc. (which are called primitives) and classes when you return them. They return the same way, and a different type is returned.
public Potato weirdMethod(Elephant e) {
System.out.println(e);
return new Potato();
}
That would work fine if you defined the classes "Potato" and "Elephant."
(Edit: as Chris McCabe clarified in the comments, when you return an object it is pass-by-reference, so you can change it and it will change the actual object you returned. Primitives are pass-by-value so if you get a primitive from a method and change it, the original will be unaffected.)
In this case, looks like you want to be using a constructor. http://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html
The official java tutorials are a great place to start with more-ever I would recommend books like Head First Java which are really good for java beginners and will help you get a grip on java fundamentals.
Being Specific to your question java methods can return either primitives like int,float etc.,inbuilt Class object instances like Integer , or custom classes that you create in your java application like "Polica " which you have mentioned above.
Also note that within an instance method or a constructor, this is a reference to the current object — the object whose method or constructor is being called. You can refer to any member of the current object from within an instance method or a constructor by using 'this'.So in your case when your method returns 'this' and method signature says it returns 'Polica' that means that the method "stavi" is part of the Class 'Polica'and is refering to the current instance of 'Polica'.

toString: When is it used?

I have a class
class Configuration {
// various stuff
#Override
public String toString() {
// assemble outString
return outString;
}
}
I also have another class
class Log {
public static void d(String format, Object... d) {
// print the format using d
}
}
The Log class works perfectly fine, I use it all the time. Now when I do this:
Configuration config = getConfiguration();
Log.d(config);
I get the compiler error The method d(String, Object...) in the type Log is not applicable for the arguments (Configuration). I can solve this:
Log.d("" + config); // solution 1
Log.d(config.toString()); // solution 2
My problem: How is this different? In the first solution, the compiler notices that it has to concatenate two Strings, but the second one is a Configuration. So Configuration#toString() is called and everything is fine. In the compiler error case the compiler sees that a String is needed, but a Configuration is given. Basically the same problem.
Needed: String
Given: Configuration
How are these cases different and why is toString not called?
While designing the language, someone decided that when a programmer appends an arbitrary object to a string using the + operator, they definitely want a String, so implicitly calling toString() makes sense.
But if you call an arbitrary method that takes a String with something else, that is simply a type error, exactly what all that static typing is supposed to prevent.
The line
"" + config
gets translated to something like
StringBuilder sb = new StringBuilder("");
sb.append(config);
where the second line calls
StringBuilder.append(Object obj);
This method calls obj.toString() to get the String representation of the object.
On the other hand, the first parameter of Log.d must be a String, and Java doesn't automatically call toString() to cast everything to a String in that case.
One of the common use of toString(), is print() and println() methods of PrintStream, as in:
System.out.print(object);
System.out.println(object);
Basically, these two methods will call toString() on the passed object. This is one of the Polymorphism's benefits.
Nice Question...
But,
Compiler does not call a method to match formal parameters. it simply tries to cast the objects if possible.
But when you use the "+" operator the compiler executes the toString() method of its arguments (in case they are objects) by default.
In one case you are passing an object argument to an operator which expects objects.
In the earlier case you are passing an object argument to a function which expects string.
Basically function/operator signature is different.
It is almost incidental [in the context of this question] that .tostring called when + is applied. It takes an object and does something.
For all you know, you might be passing in object when string is required by mistake. So it can't blindly do .tostring()
You are passing Configuration class object argument in case 1 but in the case 2 , you are passing string argument . so no error occures.

Categories