4

Let's take the following class with a static inner class.

@Getter
@Setter
public class Request {
    private String contactUrl;
    private Resources resources;

    @Getter
    @Setter
    private static class Resources {
        private String basketId;
        private String customerId;
    }
}

I need to access the basketId from another class like this:

Request request = new Request();
request.getResources.setBasketId("5");

This won't compile unless I define the Resources class as public.

Is there any other way using Lombok accessing this field while keeping Resources private?

Robert Strauch
  • 12,055
  • 24
  • 120
  • 192
  • 1
    What’s the problem with making the inner class public? If it’s returned from the getter, users already know it exists and what methods it has. What are you trying to achieve by making it private? – Bohemian Nov 30 '19 at 22:05
  • Non-static inner class objects require an object of the enclosing class, while nested (static) class objects do not. This is one valid reason, altho I don't say it is the OP's reason. – clapas Jul 09 '21 at 08:35

2 Answers2

4

You can use @Delegate to effectively 'copy' every method that your private inner class has to the outer (and the implementation just calls that method on the inner):

@Delegate private Resources resources;

Note that having a type used in a signature (the constructors, fields, methods, etc – the non-code aspects of a type) such that the type is less visible than the signature, is really weird: Here you have a public method that returns an effectively invisible type (Resources) to all code that isn't in this very file. This is a bad idea; nobody can usefull call this method. Either get rid of the getter and setter (For example, by using Delegate instead), or make the Resources inner class public.

Let's take a step back: What are you trying to accomplish? For example, if you don't want anybody to use that inner Resources class without the outer's knowledge, that's easily doable: Just make a private constructor in Resources, and, voila. Now nobody can make instances except your outer.

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72
1

To keep Resources private, you can delegate the setter method e.g.:

@Getter
@Setter
public class Request {
    private String contactUrl;
    private Resources resources;

    @Getter
    @Setter
    private static class Resources {
        private String basketId;
        private String customerId;
    }

    public setBasketId(String id) {
        resources.setBasketId(id)
    }
}

Or you can use reflection: Set private field value with reflection

jcal
  • 871
  • 5
  • 14
  • When speaking about delegate, you could probably use `@lombok.Delegate private Resources resources`. But I'm unsure whether exposing the inner class details this way is any better than exposing the class itself. – maaartinus Dec 01 '19 at 06:16