Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass constant class as argument and store it

Tags:

java

Psuedo-code

The snippets provided are to be taken as psuedo-code. I am open to if there is a different solution that is the standard way to solve this problem.

This is about the expected usage:

Some clarification:

  • One, and only one configuration will be used per application. It will not be changed during runtime.
  • Main.java can not allow @Override.
  • Configuration.java can not be an Interface as default values should be given to fields not overridden.
  • Configuration.java will grow quite substantially from its two current fields. Rendering the builder-pattern very messy to work with.

Configuration.java

public class Configuration
{
    public static int getFoo () { return 1; }
    public static int getBar () { return 2; }
}

UserDefinedConfiguration.java

public class UserDefinedConfiguration extends Configuration
{
    @Override
    public static int getFoo () { return 3; }
}

Main.java

public final class Main {
    private final Configuration config;

    // default configuration
    public Main () {
        this (Configuration.class);
    }

    // user-defined configuration
    public Main (Class<? extends Configuration> config) {
        this.config = config;
    }

    // dummy-test
    public void printFoo () {
        System.out.println(config.getFoo());
    }
}

Now to the main question, how to accomplish this? If no (or Configuration is passed) getFoo() should return 1, if the UserDefinedConfiguration is passed then 3.

One way to accomplish it is to store an instance of Configuration. However, it feels redundant when all the getters are static. It doesn't make much sense to not have them as static either.

Note: This is taken into account.

like image 737
Emz Avatar asked Dec 22 '15 10:12

Emz


People also ask

How do you pass a constant argument in Java?

To make any variable a constant, we must use 'static' and 'final' modifiers in the following manner: Syntax to assign a constant value in java: static final datatype identifier_name = constant; The static modifier causes the variable to be available without an instance of it's defining class being loaded.

Can we pass constant through a function?

const values in declarations do not affect the signature of a function, so they should not be put there.

What is const argument?

A constant argument is the one whose modification cannot take place by the function. Furthermore, in order to make an argument constant to a function, the use of a keyword const can take place like- int sum (const int a, const int b).

How do you define a constant inside a class?

A class constant is declared inside a class with the const keyword. Class constants are case-sensitive. However, it is recommended to name the constants in all uppercase letters.


1 Answers

Unless playing with dirty reflection, I'm afraid you'll have to work with instances instead of classes. From @JonSkeet:

A singleton allows access to a single created instance - that instance (or rather, a reference to that instance) can be passed as a parameter to other methods, and treated as a normal object.

A static class allows only static methods.

This is exactly what you're trying to do: passing the configuration as a parameter.


I would create an abstract class defining the default values:

public abstract class Configuration {
  public int getFoo() { return 1; }
  public int getBar() { return 2; }
}

Then, one singleton per concrete configuration:

public final class DefaultConfiguration extends Configuration {
  public static final Configuration INSTANCE = new DefaultConfiguration();
  private DefaultConfiguration() {}
  // nothing to override, use the default values
}

public final class UserDefinedConfiguration extends Configuration {
  public static final Configuration INSTANCE = new UserDefinedConfiguration();
  private UserDefinedConfiguration() {}
  @Override public int getFoo() { return 3; } // specific `foo` value
}

Finally, in your Main:

public class Main {
  private final Configuration config;
  public Main() { this(DefaultConfiguration.INSTANCE); }
  public Main(Configuration config) { this.config = config; }
}

Plus, note that Java 8 allows default methods implementations within interfaces; Configuration could then be an interface:

public interface Configuration {
    default int getFoo() { return 1; }
    default int getBar() { return 2; }
}
like image 115
sp00m Avatar answered Oct 05 '22 08:10

sp00m