7

I learned about local classes on the Oracle Java Tutorial page. Not nested classes.

I don't see myself using local classes. It makes the code look messy and you can easily do what local classes do with having a class declared separately.

But maybe I'm missing some use cases for it. Are there situations where you would prefer using local classes over other approaches or are local classes just an antiquated feature no one really uses?

2

Local classes are just a way to encapsulate some state and behavior locally.

But I think you're right; if it's worth doing, it's worth doing in a way that is reusable, and that means public classes, not local ones. Local classes seem to me to be a bit of a code smell because they are indicative of an outer class definition that is too broad; that is, it is being asked to do too much.

| improve this answer | |
6

I can think of one use case for local classes - creating a structure for an object that will be returned to a mechanism that uses reflection to access it. I don't know though if anyone uses it for this purpose...

For example, lets say you have an AJAX web framework. The server side has a routing mechanism that routes a requests to Java methods, and those methods should return objects that the mechanism will convert to some serialization format(XML/JSON/whatever) and send back to the client.

The client does not need the Java class, because it runs JavaScript and only care about the class's bean structure. The framework doesn't need that class either not at compile time anyways. The only place that class will be used is the method that creates an object of it and returns it to the framework's routing system.

Now, you can't use anonymous classes for this because you won't be able to populate their properties(unless you use an ugly hack and create a single method that sets all the properties and return this as Object...), but if you use a local class it can have a constructor and setter properties you can call more than once.

Like you said, you could also use separate class definitions for this, and I know the widely preached dogma says that class declarations should be placed in the most visible and accessible place possible, but I'm gonna risk being burned at the stake and claim that not every single piece of code needs to be widely reusable!

There are disadvantages to code reuse. One of them is that you can't change reusable code easily, because you don't know where else it's being used. A large portion of the design patterns that run around are dedicated to solve this disadvantage, but sometimes it's just not worth it, and it's better to simply limit the code to a be only usable in a single point so you could easily change it when you need to.

For example, let's say method foo returns to our framework a Result object that has 3 fields - a, b and c. Another method, bar, also needs to return those 3 fields, and since you don't want to copy 28 lines of code ((1 line of for declaration + 3 lines for setter + 3 lines for getter) * 3 fields + 2 lines for the class + 5 lines for constructor = 28 lines of code. Java is that freaking verbose...) you use Result in bar.

Now, what if you want to return from foo another field - d? You can't just add it to Result, because bar uses Result as well and you can't just have it returning a d, because bar doesn't return d, and there might be other methods that use Result for other things. So, you apply the open-close principle and subclass Result into Result2 that adds the d field.

Repeat 10 times, and you get a weird hierarchy of classes used solely to create data objects that will be handled by reflection...

Wouldn't it be better if each method had it's own Result local class that you could alter freely because it's local and there is no risk other methods will use it?

| improve this answer | |
0

I sometimes use a Local class when I need to do recursion and I have to pass additional state to a method call which is of no concern to the user.

Let's say I wanted to detect cycles in a graph and return the first cycle found. For this I'd need the set of objects being visited, the set that is already visited and perhaps some other objects (needed to restrict the set and to find dependencies for example). That's four parameters to pass around.

You'd also need a "starter" method that sets up the visited and visiting sets, and the recursive method itself.

List<T> hasCycle(List<T> objects);  // returns visiting list, which contains the cycle
boolean hasCycleRecursive(T object, Set<T> visited, List<T> visiting);

With a Local class, you would not need to pass so much parameters around:

List<T> hasCycle(List<T> objects) {
    class CycleDetector { 
        Set<T> visited = new HashSet<>();
        List<T> visiting = new ArrayList<>();

        List<T> hasCycle() { }
        boolean hasCycle(T object) { }
    }

    return new CycleDetector().hasCycle();
}

It's also possible to do this with Lambda's, but less readable and more restrictive since captured variables cannot be modified (although their content can, so for this example it would work as only Collections are used).

Local methods might be a better solution once Java supports them.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.