Java is a sort of purely class-based programming language. So, Yes, it and everything needs to be a part of a class.
You are right, you can make a Utility class making methods public static
in this way methods can be called without instantiating the class.
Answer to question in the comment:
Why would someone write Object.method() instead of just method()?
Object
class is a standard class in java.lang
package. You should not create your class named Object
otherwise you will need to specify java.lang.Object
everywhere you use java.lang.Object
.
Now you probably meant
Why would someone write MyUtilClass.method() instead of just method()?
Suppose you have a class MyUtilClass
as follows
public class MyUtilClass {
public static int utilMethodA() {
return 1;
}
public static boolean utilMethodB() {
int value = utilMethodA();
if(value == 1)
return true;
else
return false;
}
}
And suppose you have another class MyClass
as
public class MyClass {
public void classMethod() {
int value = MyUtilClass.utilMethodA();
}
}
Here if you see in MyUtilClass
, utilMethodB()
uses utilMethodA()
without writing MyUtilClass.utilMethodA()
(however, we could write it that way also). Here we did not need to write it as MyUtilClass.utilMethodA()
because compiler can find the utilMethodA()
without fully specifying it's class because it is present inside it's own class.
Now, In Myclass
's myMethod()
, we must specify MyUtilClass.utilMethodA()
(without it, it won't work), because the compiler has no way of figuring out that you meant to call utilMethodA()
of MyUtilClass
. There could be hundreds of classes with a method named utilMethodA()
, the compiler has no way of finding out which one of the hundred methods you want to call.
Note:-
Also, you can do static import
of MyUtilClass.myMethod()
like
import static my.package.name.MyUtilClass.myMethodA()
and then use utilMethodA()
inside MyClass
without prefixing MyUtilClass
(but you already informed compile by static import that you will be using utilMethodA()
of MyUtilClass
right?)
Looks cool to you? No!
This is rather a bad way because
- It makes code looks unobvious. In a large class, it may seem that
method
utilMethodA()
is a local method defined somewhere in
MyClass
.
- Also, it can generate ambiguity to the compiler if more than one static import of
utilMethodA()
is done. As compiler has no way of figuring out which of the two you intend to use.
(Edit) Regarding Lambda Expression
Lambda expression is pretty cool stuff added in Java 8. They are basically a kind of function. They provide you the power to define a function right where they need to be used. For example in this link that you provided, see the example shown below syntax of lambda
, there the statement
ArrayList<Integer> arrL = new ArrayList<Integer>();
arrL.add(1);
arrL.add(2);
arrL.add(3);
arrL.add(4);
arrL.forEach(n -> { if (n%2 == 0) System.out.println(n); });
Basically, what we are doing here is, we are defining a function, if n
is multiple of 2, we print n. We are doing it forEach
element of arrL
. Did you see, we defined the function to be executed on each element right inside a function call forEach()
. That's the beauty of lambda expression.
Now, coming to your question,
So the primary benefit of lambda (besides syntax) is to make it easier to implement functional interfaces (compared to what alternative)?
Yes, sort of. Easy in terms of not creating a separate class implementing the interface and then implementing the abstract method and then calling that implemented method.
This becomes lots of work, especially if you need to call that method only once for example,
Consider the Functional Interface FuncInterface
defined as in the link in your question:
interface FuncInterface {
// An abstract function
void abstractFun(int x);
// A non-abstract (or default) function
default void normalFun() {
System.out.println("Hello");
}
}
Now, you want two kind of implementation to your functional interface:
- One that provides twice of the passed
int x
.
- Another one that provides square of passed
int x
.
So, you make two implementations of it:
First FuncInterfaceTwiceImpl
public class FuncInferFaceTwiceImpl implements FuncInterface {
@Override
public void abstractFun(int x) {
System.out.println(2 * x);
}
}
Second, FuncInterfaceSquareImpl
as
public class FuncInterfaceSquareImpl implements FuncInterface {
@Override
public void abstractFun(int x) {
System.out.println(x * x);
}
}
Now, you call them as
public class MyClass {
public static void main(String[] args) {
FuncInterface interfaceTwiceObject = new FuncInferFaceTwiceImpl();
interfaceTwiceObject.abstractFun(5);
FuncInterface interfaceSquareObject = new FuncInterfaceSquareImpl();
interfaceSquareObject.abstractFun(5);
}
}
It prints
10
25
Now, what you had to do?
- You had to create two separate Classes (in separate new files or
could have made private classes in the same file that of
MyClass
),
each implementing the abstract method.
- Then you instantiated objects of each class and called them
respectively in the
main
function.
What if this is the only place where you had to call this twice
and square
thing? You had to make two classes just to use them only once. This effort is too much!!
- What if you want to call it without creating new classes and implementing methods in a class?
- What if I tell you only provide me the method body, I will do the work for you without you to bother about implementing interface and overriding methods?
Here comes the Lambda magic. Instead of making any impl
classes just
- head straight towards the main method
- Instantiate two objects of
FuncInterface
providing only method body in Lambda expression.
- Call abstract method from objects just like below
public class MyClass {
public static void main(String[] args) {
FuncInterface interfaceTwiceObject = (n) -> System.out.println(2*n);
interfaceTwiceObject.abstractFun(5);
FuncInterface interfaceSquareObject = (n) -> System.out.println(n*n);
interfaceSquareObject.abstractFun(5);
}
}
And boom, the output is
10
25
Just one more time where Lambda saved your day!!