Record Class EmailAddress

java.lang.Object
java.lang.Record
com.google.common.labs.email.EmailAddress

public record EmailAddress(Optional<String> displayName, String localPart, String domain) extends Record
Represents an email address according to RFC 5322, designed as a modern, type-safe replacement for javax.mail.InternetAddress.

For example:


 EmailAddress emailAddress = EmailAddress.parse("john-doe@gmail.com");
 

RFC 5322 Compliance Profile

  • Address Specification (addr-spec): Supports the standard local-part@domain format (RFC 5322 §3.4.1).
  • Name-Addr: Fully supports "display-name" <addr-spec> syntax (RFC 5322 §3.4).
  • Quoted-Strings: Complies with RFC 5322 §3.2.4, supporting backslash-escaped characters within double-quoted display names.
  • Phrases (unquoted names): Supports RFC 5322 "atoms" in display names, forbidding "specials", i.e. the ()<>[]:;@\," characters, while allowing periods for real-world usability (e.g., "J.R.R. Tolkien").
  • Folding White Space (FWS): Supports optional whitespace between the display name and the angle-bracketed address.

Comparison with javax.mail.InternetAddress

FeatureInternetAddressEmailAddress
ImmutabilityMutable pojoImmutable record
DNS labelsPermissive (allows illegal hyphens)Strict (RFC 1035/1123 63-char limit)
ValidationLazy – need to call validate()Eager – parse() throws if invalid
I18nOften requires Encoded-WordsNative BMP support

Intentionally Omitted Legacy Features

To maintain compatibility with modern MTAs (Gmail, Outlook) and mitigate header injection risks, the following RFC 5322 edge cases are excluded:

  • Quoted Local-Parts: (e.g., "john doe"@domain) - Deprecated in practice.
  • Comments (CFWS): (e.g., name(comment) <addr>) - De facto obsolete.
  • Domain Literals: (e.g., user@[192.168.1.1]) - IP routing is rarely supported.
  • Obsolete Syntax: (RFC 5322 §4) - Legacy syntax like "quoted-pairs" in unquoted names.
Since:
9.9.4
  • Field Details

    • PARSER

      public static final Parser<EmailAddress> PARSER
      The parser for email address, according to RFC 5322, and supporting BMP characters.

      Prefer using the parse(java.lang.String) convenience method. This constant is to be used for composition, for example to parse a list of email addresses:

      
       EmailAddress.PARSER.skipping(whitespace()).parseToStream(emailAddresses).toList();
       
  • Constructor Details

  • Method Details

    • withDisplayName

      public EmailAddress withDisplayName(String displayName)
      Returns an otherwise equivalent EmailAddress but with displayName.
    • of

      public static EmailAddress of(String localPart, String domain)
      For example: EmailAddress.of("user", "mycompany.com").
    • address

      public String address()
      Returns the addr-spec, in the form of user@mycompany.com.
    • toString

      public String toString()
      Returns the full email address, in the form of local-part@domain or "display name" <local-part@domain>. Backslashes and double quotes in the display name are auto-escaped.
      Specified by:
      toString in class Record
    • parse

      public static EmailAddress parse(String address)
      Parses address and throws Parser.ParseException if failed.
    • parseAddressList

      public static List<EmailAddress> parseAddressList(String addressList)
      Parses addressList according to RFC 5322 and returns an immutable list of EmailAddress.

      Both colon (,) and semicolon (;) are supported as delimiters, with whitespaces ignored. Trailing delimiters are allowed.

      Empty input will result in an empty list being returned.

    • hashCode

      public final int hashCode()
      Returns a hash code value for this object. The value is derived from the hash code of each of the record components.
      Specified by:
      hashCode in class Record
      Returns:
      a hash code value for this object
    • equals

      public final boolean equals(Object o)
      Indicates whether some other object is "equal to" this one. The objects are equal if the other object is of the same class and if all the record components are equal. All components in this record class are compared with Objects::equals(Object,Object).
      Specified by:
      equals in class Record
      Parameters:
      o - the object with which to compare
      Returns:
      true if this object is the same as the o argument; false otherwise.
    • displayName

      public Optional<String> displayName()
      Returns the value of the displayName record component.
      Returns:
      the value of the displayName record component
    • localPart

      public String localPart()
      Returns the value of the localPart record component.
      Returns:
      the value of the localPart record component
    • domain

      public String domain()
      Returns the value of the domain record component.
      Returns:
      the value of the domain record component