0

When declaring methods in Java, do they need to be a part of a class? I am familiar with the idea of a Utility Class:

"Utility Class, also known as Helper class, is a class, which contains just static methods, it is stateless and cannot be instantiated. It contains a bunch of related methods, so they can be reused across the application."

However, can one just create a method separate from any class altogether? (I'd assume scope becomes public by default and declaring anything else for scope might result in an error).

If this is not possible, perhaps that would explain the need for Utility Classes, but I wasn't sure as I hadn't thought about this before - I assumed naturally you could make functions separate from any specific class, but I had been looking through various code samples and couldn't find a specific example where this was occurring.

Part of the reason I am asking this is I was reviewing this article (and mentioned in point 2):

https://www.geeksforgeeks.org/lambda-expressions-java-8/

In it, it states: Lambda expressions are added in Java 8 and provide below functionalities.

1) Enable to treat functionality as a method argument, or code as data.

2) A function that can be created without belonging to any class.

3) A lambda expression can be passed around as if it was an object and executed on demand.

sgx
  • 1,265
  • 3
  • 19
  • 36
  • 1
    What are you using to learn Java, exactly? It should have explained this to you quite carefully, quite early on. – Karl Knechtel May 15 '20 at 03:10
  • I modified my question to provide a little more context and if you had any further comments on that would be appreciated. – sgx May 15 '20 at 04:58

2 Answers2

4

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!!

CodeTalker
  • 1,683
  • 2
  • 21
  • 31
  • Why would someone write Object.method() instead of just method()? – sgx May 15 '20 at 03:06
  • 1
    Java is not purely OOP by any reasonable definition, and there are plenty of languages that have a *much stronger* claim to "OOP" than Java yet do not require you to put everything into a class. OOP is **not about classes**. If it were about classes, it would be called COP. – Karl Knechtel May 15 '20 at 03:09
  • What does it mean then to be "purely OOP" – sgx May 15 '20 at 03:10
  • 1
    @jeremy It means to support only the object oriented paradigm. A pure OOP language would be something like [Smalltalk](https://en.wikipedia.org/wiki/Smalltalk). Java supports multiple paradigms. – Vince May 15 '20 at 03:20
  • 1
    @KarlKnechtel Yes, should not have used 'pure object oriented' so casually. Thanks for pointing out. I wanted to say sort of class oriented where everything needs to be inside a class. Will edit the answer. – CodeTalker May 15 '20 at 03:23
  • 1
    @jeremy answered your question in edit of my anwser. – CodeTalker May 15 '20 at 03:44
  • 1
    Thanks - this was very helpful. For my question I actually meant, Object in the general sense - i.e. why would someone write "random object name".method() instead of method() to call that method? Is it simply to distinguish between another class or object that has that method? I thought there might be some other reason besides this. – sgx May 15 '20 at 04:16
  • I modified my question to provide a little more context and if you had any further comments on that would be appreciated. – sgx May 15 '20 at 04:58
  • Thanks - if you can provide a little discussion maybe just clarifying the concepts of lambda, that would be appreciated. I have been reading quite a bit but the concept is still not really clear. Is the main benefit for syntax purposes? The site from where the article above is from is pretty solid, so I am wondering if those 3 points are really all there is to lambda as well – sgx May 15 '20 at 07:11
  • 1
    Yes, explaining clearly, that's what I wanted to do, that's the reason I asked some time. Till then check out https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html and let me know if you still need explanation. – CodeTalker May 15 '20 at 07:16
  • No worries - take your time - one thought I am having which maybe you can comment on /address: so the primary benefit of lambda (besides syntax) is to make it more easy to implement functional interfaces (compared to what alternative)? – sgx May 15 '20 at 07:22
  • 1
    @jeremy check my edited answer. – CodeTalker May 15 '20 at 08:44
  • 1
    Also, I am deleting non-informative comments, just to clear the clutter. Please you also do the same. – CodeTalker May 15 '20 at 08:44
  • Awesome thanks for your help! This is very clear and great info! – sgx May 15 '20 at 17:30
  • 1
    @jeremy this question is different from the one marked as duplicate.. raise flag to reopen question. – CodeTalker May 15 '20 at 18:04
  • So in Java without lambda expressions, you can't pass methods as an argument to another method or class? – sgx May 15 '20 at 21:06
  • 1
    If you are asking before Java 8, You can pass methods but you can't define methods in a method call or inbetween. – CodeTalker May 16 '20 at 03:33
  • Thanks! Yes - now I understand what a Lambda does and how it is useful; I just wanted to get a little more clarity on kind of what problem it solved and what the alternative was prior to its existence – sgx May 16 '20 at 04:06
0

Yes all methods in Java have to be part of a class. You cannot create a method (static or otherwise) which is not associated with a class.


EDIT

Before I answer your question, I will point out that lambda expressions were introduced in Java 8 through the concept of SAM types. In addition, a bit of syntactic sugar was also introduced to facilitate the creation of these types.

When you hear the term "Lambda expression" in Java, you should always remember that they are expressions. Your confusion stems from thinking that lambda expressions evaluate to a pure function not associated with a class or object; well this is simply not the case in Java and I will show you why.

Lambda expressions are not functions

I can now see where your confusion comes from because that article you are reading made a false claim when they say that lambda expression is:

A function that can be created without belonging to any class.

This is simply not true. A lambda expression in Java is not a function. Take the example they give for instance.

interface FuncInterface 
{ 
    // An abstract function 
    void abstractFun(int x); 

    // A non-abstract (or default) function 
    default void normalFun() 
    { 
       System.out.println("Hello"); 
    } 
}

class Test 
{ 
    public static void main(String args[]) 
    { 
        // lambda expression to implement above 
        // functional interface. This interface 
        // by default implements abstractFun() 
        FuncInterface fobj = (int x)->System.out.println(2*x); 

        // This calls above lambda expression and prints 10. 
        fobj.abstractFun(5); 
    } 
} 

Proof

Now take the comment they have in the main method:

lambda expression to implement above functional interface

From the start they admit that the next line of code implements a functional interface. However functions in Java do not implement interfaces, only classes or other interfaces can do that!

Now, they even go ahead and "call" this function:

This calls above lambda expression and prints 10.

except instead of directly invoking the function (as anyone would if this was really a function), they use the property accessor notation (.) to access the actual method they wanted to call, which means what we have here is not a function, but actually an instance of an anonymous class.

Furthermore, since this object actually contains another method (normalFun), one might ask the question, which one do I use when I want to pass this "function" to another method? This is not a question that is commonly (if ever) asked in the context of lambda functions because there is only one thing to do with a lambda function and that is to call it.

In closing

Java has lambda expressions, not lambda functions.

What makes it a lambda expression is simply the syntactic sugar introduced in Java 8 that uses the () -> { } notation. Unfortunately, many fans of functional programming began associating the term "Lambda function" with objects created using this syntax, and this has led to the confusion you have expressed in your question.

To rehash what I answered previously, all functions in Java are part of a class, and you cannot have a function which is not associated with an object, nor can you create a function outside a class.

HTH

smac89
  • 39,374
  • 15
  • 132
  • 179
  • I modified my question to provide a little more context and if you had any further comments on that would be appreciated. – sgx May 15 '20 at 04:58
  • @Grateful I never said that all code belongs to a class, but even if I did, that's not entirely untrue either. Even your variable defined inside a method is technically still inside a class because that method has to be inside a class. Maybe you meant to reply to the [current accepted answer](https://stackoverflow.com/a/61811002/2089675), which does specifically say that everything is part of a class? Moreover, lambda functions aka anonymous functions belong to the anonymous *class* which implements the SAM interface. – smac89 Feb 28 '23 at 18:19
  • @smac89 I appreciate your replies. They have helped me to rectify some of my understanding. So, I've deleted my original comments, to prevent misleading anyone. Once again, thank you! – Grateful Mar 01 '23 at 03:57