0

Not sure if this is possible in JAVA, and also don't know what it's called so I'm not sure what to look for, but if it is possible I really wanted to implement the same in my logic. I know we can substitute value but how to substitute variable that I am not sure.

public interface Constants {
 GENDER_${MALE} = "where Gender = 'MALE' ";
 GENDER_${FEMALE} = "where Gender = 'FEMALE' ";
}

public class Impl {
  System.out.println(Constants.GENDER_MALE);
}

Expected O/P : where Gender = 'MALE';

I just don't want to use if else condition, if Male then return male specific where clause else female.. because in actual code there are almost 30-35 if else conditions, just want to reduce that, if possible.

Kalpesh
  • 694
  • 2
  • 8
  • 28
  • 4
    Not possible (like this) in Java, as java is a statically compiled language, and there is no way to have interfaces that do "dynamics" like this. You could look into defining an enum that implements an interface that returns your where clause instead. – GhostCat Dec 06 '21 at 14:29
  • 1
    If you're building SQL queries, you should probably be using JPA libraries, not hard coded sql filter strings – OneCricketeer Dec 06 '21 at 14:29
  • You can use polymorphism to avoid large conditional constructs. Simply have one abstract class or interface that defines a method, and classes that extend the abstract class or implement the interface, and each class implements the behavior specific to their condition in their override of the abstract class or interface method. – JustAnotherDeveloper Dec 06 '21 at 14:32
  • `System.out.printf("where Gender = '%s' ", "MALE");` (String.format; constants you have to do yourself. – Joop Eggen Dec 06 '21 at 14:32
  • 3
    Not only it is not possible in Java, but I don't even see the advantage of doing this in real life. Your variable name should not vary based on its value, nor you should delay naming a variable until a value is set. This is not even practical for constants in my opinion. Using your example, what is wrong with naming the variable just `GENDER`? – hfontanez Dec 06 '21 at 14:36
  • 1
    Since this seems to be about building an SQL statement, you should learn about `PreparedStatement` and [How does a PreparedStatement avoid or prevent SQL injection?](https://stackoverflow.com/q/1582161/2711488) – Holger Dec 06 '21 at 16:47
  • @GhostCat It's possible with reflection. See my answer. – ʀᴀʜɪʟ Dec 06 '21 at 17:07
  • @ʀᴀʜɪʟ Providing a method that takes an argument isn't the same as dynamically compiling interface content. – GhostCat Dec 07 '21 at 08:50
  • @GhostCat I know but, It can simulate like that. He just wants to avoid if-else logic so there is no problem in passing an argument. – ʀᴀʜɪʟ Dec 07 '21 at 10:28
  • 1
    @ʀᴀʜɪʟ The point is more like: reflection should ALWAYS be your last resort. You only use that when there is no other meaningful way to achieve what you need. Be very careful suggesting java newbies to even think about reflection. – GhostCat Dec 07 '21 at 11:56
  • @GhostCat You are right. I too don't want newbies to learn to abuse JAVA. But It's better to know about reflection than to *regret by saying* '**Impossible**'. - I agree. That's why I have also provided another approach to it. – ʀᴀʜɪʟ Dec 07 '21 at 14:20

3 Answers3

2
public enum Gender {
    FEMALE, MALE;
    public String where() {
        return "where Gender = '" + this + "' ";
    }
}

String s = Gender.MALE.where();

As this is probably an attempt to large scale modelling:

public static <T extends Enum<T>> String where(T value) {
     return "where Gender = '" + value + "' ";
}

Do not expect too much result from this all.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
2

You can put where expressions in Map where key is your variable possible value, for example:

HashMap<String, String> whereMap = new HashMap<>();

whereMap.put("MALE",   "where Gender = 'MALE' ");
whereMap.put("FEMALE", "where Gender = 'FEMALE' ");

And instead of using condition do substitution by retrieved by key value:

String varr = "MALE";
System.out.println(MessageFormat.format("SELECT * FROM EMP {0}", whereMap.get(varr)));
Sergey Afinogenov
  • 2,137
  • 4
  • 13
1

The word Impossible isn't defined for me.

Approach 1

Make a class like this,

class Constants {
    public String MALE = "where Gender = 'MALE' ";
    public String FEMALE = "where Gender = 'FEMALE' ";

    public static String GENDER_(String $argument){
        Constants constants = new Constants();
        try {
            Field field = constants.getClass().getField($argument);
            return (String) field.get($GENDER);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
            return null;
        }
    }
}

Then use it like this,

String $GENDER;  // This is your argument, either take it from the user.
System.out.println(Constants.GENDER_($GENDER));

This will do exactly what you want. And yes, we haven't used any logic here (if-else).

NOTE : Constants.GENDER_($GENDER) will return null if the argument is not a field in Constants

Approach 2

Use a Map instead of creating feild. Like this,

Map<String,String> fields = new HashMap<>();
fields.put("MALE","where Gender = 'MALE'");
fields.put("FEMALE","where Gender = 'FEMALE'");

Then use that map like this,

String $GENDER; // Your argument.
System.out.println(fields.get($GENDER));
ʀᴀʜɪʟ
  • 235
  • 1
  • 4
  • 8
  • my requirement is, I dont want to use if else.. means if (g=="MALE") { System.out.println(Constants.GENDER_MALE); else { System.out.println(Constants.GENDER_FEMALE); }... I am thinking something , Constants.GENDER_$GENDER – Kalpesh Dec 06 '21 at 14:48
  • @Kalpesh Ohh, Now I got what you want. I have edited my answer. – ʀᴀʜɪʟ Dec 06 '21 at 17:44