Home > Software design >  How to dynamically call static nested classes?
How to dynamically call static nested classes?

Time:02-16

I have the following java code:

...

public final class Constants {

    ...

    public static class Languages {
        ...
        
        public static class en_US {
            public static final String VALIDATION_REGEX = "[a-zA-Z-' ] ";
            ...
        }
        public static class en_GB {
            public static final String VALIDATION_REGEX = "[a-zA-Z-' ] ";
            ...
        }
    }

    ...
}

My problem is as follows: I receive a text and a language, and I have to check, whether that text is written only with valid alphabetic characters of that given language. My code so far is as follows:

...

public boolean isContentValid(String content, String language) {
    Boolean isCorrect = false;
    switch (language) {
        ...
        
        case "en_US":
            isCorrect = content.matches(Constants.Phrases.en_US.VALIDATION_REGEX);
            break;
        case "en_GB":
            isCorrect = content.matches(Constants.Phrases.en_GB.VALIDATION_REGEX);
            break;

        ...
        
        default:
            isCorrect = false;
    }
    return isCorrect;
}

...

This is fine and works, but as I add languages to my application, I will have to add more and more cases to my switch.

And I was wondering if in Java there is a way to dynamically name a static nested class, something like:

Constants.Phrases[language].VALIDATION_REGEX

So my above code could be something like:

...

public boolean isContentValid(String content, String language) {
    return content.matches(Constants.Phrases[language].VALIDATION_REGEX);
}

...

Thank you, and sorry if this is something super easy.

I am a JavaScript developer, and just learning Java.

CodePudding user response:

Looking at you use case maybe this is a better approach:

public enum Language {
  en_US("engUS_reg"),
  en_GB("engGB_reg");

  private final String regex;

  Language(String regex) {
    this.regex = regex;
  }

  public String getRegex() {
    return regex;
  }
}

And using this enum class write your method as follows:

public boolean isContentValid(String content, String language) {
    return content.matches(Language.valueOf(language).getRegex());
}

CodePudding user response:

You could use an enum for something like this.

"An enum can, just like a class, have attributes and methods. The only difference is that enum constants are public, static and final (unchangeable - cannot be overridden)." - [w3][1]

public enum Languages {
    EN_US {
        @Override
        public String toString() {
            return "[a-zA-Z-' ] ";
        }
    },
    EN_GB {
        @Override
        public String toString() {
            return "[a-zA-Z-' ] ";
        }
    },
}

And then you can access these values like this

Languages.valueOf("EN_US");

As mentioned by @Pshemo you could avoid a class based approach entirely and use an implementation of Map if you want something a little more lightweight

[1]: https://www.w3schools.com/java/java_enums.asp#:~:text=An enum can, just like,but it can implement interfaces).

  • Related