0

I want to know if there is something like functional creation of an object instance, maybe there is something like that?

This piece of code is written for example, it is also not working

    SimpleMailMessage mail = new SimpleMailMessage({
    setTo(email),
    setFrom(from),
    setText(text)
    });
Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • 1
    I think you might be looking for the [builder pattern](https://stackoverflow.com/questions/328496/when-would-you-use-the-builder-pattern). – OH GOD SPIDERS Jan 12 '22 at 13:37
  • 1
    That is not "functional" since the functions change the state of the object. It looks like what you want is the builder pattern. – f1sh Jan 12 '22 at 13:37
  • 1
    There's also double-brace initialization, but the builder pattern in this case would be more appropriate imo. – Rogue Jan 12 '22 at 14:00

1 Answers1

3

SPOILER: The answer ends up being 'yes, sort of', but takes some explanation before we get there.

Java, the language, has no support for this. Some languages do, it's generally called a with feature. For example, javascript's with syntax.

However, the API (as in, the author of the SimpleMailMessage class in your example) can give their class methods that make it possible to write code like this. This is generally called the builder pattern. Your 'users' would write:

SimpleMailMessage mail = SimpleMailMessage.builder()
  .to(email)
  .from(from)
  .text(text)
  .build();

This isn't voodoo magic or a java language feature - the author of SimpleMailMessage did the work:

class SimpleMailMessage {
  String from, to, text;

  SimpleMailMessage(String from, String to, String text) {
    this.from = from;
    this.to = to;
    this.text = text;
  }

  public static SimpleMailMessageBuilder builder() {
    return new SimpleMailMessageBuilder();
  }

  public static class SimpleMailMessageBuilder {
    String from, to, text;

    private SimpleMailMessageBuilder() {}

    public SimpleMailMessageBuilder from(String from) {
      this.from = from;
      return this;
    }

    public SimpleMailMessageBuilder to(String to) {
      this.to = to;
      return this;
    }

    public SimpleMailMessageBuilder text(String text) {
      this.text = text;
      return this;
    }

    public SimpleMailMessage build() {
      return new SimpleMailMessage(from, to, text);
    }
  }
}

That's a ton of code to maintain, and it's not even done: You also need a toString and equals method, and probably some getX() methods, and the builder should probably also get a toString for convenience.

Usually IDEs can generate this code for you, but you still have to look at it, and when you change a field, you have to remember to delete it all and re-run those IDE code gen tools.

A better alternative is lombok's @Builder feature. You can just write:

@Value @Builder
class SimpleMailMessage {
  String from, to, text;
}

and you're done. Lombok takes care of making all tools (not just javac, but also your editor) think that it's got all those methods.

DISCLAIMER: I'm a core maintainer of Project Lombok.

NB: This has absolutely nothing to do with 'functional'. Then again, the meaning of the word 'functional' as applied to programming is rather nebulous at this point, in the sense that people use that word and mean wildly different things with it. So, who am I to cast stones here :) – just giving you a headsup that when you say "I want functional syntax in java to make simple objects", it is very unlikely the persons who hear/read that sentence have any clue about what you meant with that.

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72
  • Was going to leave another answer as an alternative but question has been locked, they also have the option of combining the `Builder` pattern with the `Consumer` class (https://medium.com/beingprofessional/think-functional-advanced-builder-pattern-using-lambda-284714b85ed5) - which would possibly fit in with the style they have suggested in their question – Popeye Jan 12 '22 at 16:18