I want to declare static(or not static) variable inside Enum. I need this because I want to associate enum values with some strings. But i Don't want to hardcode this strings. I want to use my application-wide class with String constants.
I.e. I want to write like this inside enum declaraton, but there compile time error:
public enum MyEnum {
private static final AppConstants CONSTANTS = AppConstants.getInstance();
ONE(CONSTANTS.one()),
TWO(CONSTANTS.two());
}
How I can put in enum a field?
It's one of the limitations, the enum values must be specified first but you can always refer to the same singelton in every instantiation...
enum MyEnum {
ONE(Test.getInstance().one()),
TWO(Test.getInstance().two());
public final String val;
MyEnum(String val) { this.val = val; }
}
Example that outputs "hello":
public class Test {
public static void main(String[] args) {
System.out.println(MyEnum.ONE.val);
}
public String one() {
return "hello";
}
public String two() {
return "world" ;
}
static Test instance;
public synchronized static Test getInstance() {
if (instance == null)
instance = new Test();
return instance;
}
}
It's a bit hacky. But you'll have to change your AppConstants class a bit.
public enum MyEnum {
ONE(getConstant("one")),
TWO(getConstant("one"));
private static final AppConstants CONSTANTS = AppConstants.getInstance();
private static String getConstant(String key) {
// You can use a map inside the AppConstants or you can
// invoke the right method using reflection. Up to you.
return CONSTANTS.get(key);
}
private MyEnum(String value) {
}
}
The enum constants need to be the first elements in the Enumeration
public enum MyEnum {
ONE,TWO;
private static final AppConstants CONSTANTS = AppConstants.getInstance();
#Override
public String toString() {
if(this==ONE){
return CONSTANTS.one();
} else if(this==TWO){
return CONSTANTS.two();
}
return null;
}
}
Related
I have this class that I use as a singleton this way:
FlagOfficer.instance().someVariable
Here is the current implementation of the class:
public class FlagOfficer {
public FlagOfficer() {
}
static FlagOfficer flagOfficer = null;
public static FlagOfficer instance() {
if (flagOfficer == null) {
flagOfficer = new FlagOfficer();
}
return flagOfficer;
}
public boolean getLastBackupDate;
public boolean syncProcessStartedOnce;
}
I am right now reading the "Effective Java" book where they say the best way to implement the singleton pattern is to use single-element enum type
Here is an example form the book:
public enum Elvis {
INSTANCE;
public void leaveTheBuilding() { ... }
}
So how do I transform my class so that it uses this pattern? And how do I use it afterwards?
public enum FlagOfficer {
// Enum instances/values should be declared first.
// Use INSTANCE(arg1, ..) if constructor accepts agruments.
INSTANCE;
// Constructor can accept arguments as well.
private FlagOfficer() {
}
private Date lastBackupDate;
private boolean syncProcessStartedOnce;
public Date getLastBackupDate() {
return lastBackupDate;
}
public boolean isSyncProcessStartedOnce() {
return syncProcessStartedOnce;
}
}
Usage:
FlagOfficer fo = FlagOfficer.INSTANCE;
im using interface to accesses the project constant
this is my interface
public interface ConstantValues {
interface PaymentType {
public static final String CREDIT_CUSTOMER = "credit";
public static final String CASH_CUSTOMER = "cash";
}
interface PaymentMethode {
public static final String CREDIT_CARD = "creditcard";
public static final String VISA_CARD = "visacard";
public static final String MASTER_CARD = "mastercard";
}
}
im accessing this values form the java class like in the below
ConstantValues.PaymentType.CREDIT_CUSTOMER
or
ConstantValues.PaymentType.VISA_CARD
but i want to know how to do this using enum, because using a
interfaces to define constant is bad practice can please anybody
tell me how to do that using enum and how to access it from java class?
Here you go:
enum PaymentType {
CREDIT_CUSTOMER,
CASH_CUSTOMER;
}
enum PaymentMethod {
CREDIT_CARD,
VISA_CARD,
MASTER_CARD;
}
Use it like:
PaymentMethod meth = PaymentMethod.VISA_CARD;
etc.
public class Enums {
public enum Test {
FIRST,
SECOND,
THIRD
}
public enum Test2 {
FIRST("first"),
SECOND("second"),
THIRD("third");
private final String value;
Test2(String value) {
this.value = value;
}
}
public static void main(String[] args) {
System.out.println(Enums.Test.FIRST);
System.out.println(Enums.Test2.FIRST.value);
}
}
I have a static method which needs to invoke the SportsMenComparator. But this, as we all know is not allowed. How does a static function use a comparator subclass ? Although I have workarounds, I am looking for best practices for this particular problem.
final class SportsMan {
private final String name;
private final int rank;
private final String sport;
public SportsMan (String name, int rank, String sport) {
this.name = name;
this.rank = rank;
this.sport = sport;
}
public String getName() {
return name;
}
public int getRank() {
return rank;
}
public String getSport() {
return sport;
}
}
final class Sport {
private final String sport;
private final int numberOfPlayers;
public Sport(String sport, int numberOfPlayers) {
this.sport = sport;
this.numberOfPlayers = numberOfPlayers;
}
public String getSport() {
return sport;
}
public int getNumberOfPlayers() {
return numberOfPlayers;
}
}
public final class Joins {
private Joins () {}
public class SportsMenComparator implements Comparator<SportsMan> {
#Override
public int compare(SportsMan s1, SportsMan s2) {
return s1.getSport().compareTo(s2.getSport());
}
}
public static void innerJoinSort(List<SportsMan> sportsMans, List<Sport> sportList) {
Collections.sort(sportsMans, new SportsMenComparator());
}
}
Eclipse results in the following message: No enclosing instance of type Joins is accessible where Joins is name of the enclosing class.
But this, as we all know is not allowed. How does a static function use a comparator subclass ?
You cannot use a non static reference,still you are allowed to create a new object and use it. So since you are creating a new SportsMenComparator object and passing, no issues.
For example:
public static void main(String[] args) {
List<String> s =new ArrayList<String>();
s.add(""); // allowed
}
But
List<String> s =new ArrayList<String>();
public static void main(String[] args) {
System.out.println();
s.add(""); // Error: Cannot make a static reference to the non-static field s
}
Edit:
Since you defined the comparator class inside the Joins , you need the Joins object to access the comparation inside it
Collections.sort(sportsMans, new Joins().new SportsMenComparator());
For using a Comparator, there is no difference between using it from a static- or non-static method. In either case an instance of the Comparator has to be used.
The Garbage Collector of modern JVMs is very efficient at handling short-lived objects. Therefore the penalty to be paid for using a fresh instance (via new) every time is usually no issue. However, if you don't want to use a fresh instance every time, I think the best option would be to add a static field to your SportsMenComparator, containing a singleton instance of the comparator:
public class SportsMenComparator implements Comparator<SportsMan> {
public static final SportsMenComparator instance=new SportsMenComparator();
#Override
public int compare(SportsMan s1, SportsMan s2) {
return s1.getSport().compareTo(s2.getSport());
}
}
public static void innerJoinSort(List<SportsMan> sportsMans, List<Sport> sportList) {
Collections.sort(sportsMans, SportsMenComparator.instance);
}
The problem is that you try to access an instance element (in this case it is a class, indeed the same as with a filed or method) within a static method, which is not associated with an instance. SURESH ATTA's answer is right, but you can also make your SportsMenComparator class static and it will work. I do not sse any reason to associate your comparator with an instance of the Joins class.
One can use something like this---
public static boolean someMethod(MyObject obj1, MyObject obj2){
return obj1.compare(obj2);
}
Why you cant include parameter to the function.
public static void innerJoinSort(List<SportsMan> sportsMans, List<Sport> sportList, Comparator comparator) {
Collections.sort(sportsMans, comparator);
}
I have following fields
a(String)
b(String)
c(String)
d(boolean)
e(boolean)
Is it possible to have them all in an Enum like following?
public enum Fields {
a("A")
b("B")
c("C")
d(true)
e(false)
}
You can have them but you should define constructors which takes String or boolean as parameters.
public enum Constants {
CONSTANT_STRING1("CONSTANT_VALUE1"),
CONSTANT_STRING2("CONSTANT_VALUE2"),
CONSTANT_STRING3("CONSTANT_VALUE3");
CONSTANT_FLAG1(false);
CONSTANT_FLAG2(true);
private String constants;
private boolean flag;
private Constants(String cons) {
this.constants = cons;
}
private Constants(boolean lFlag) {
this.flag= lFlag;
}
}
It sounds like you are using an enum to store constants, which is bad practice.
It is possible, but I would advice against it. In most cases, what you really want is a common interface, which is implemented by two (or more) different classes.
Please also note that is fully legitimate for an enum to implement an interface, but it is seldom you see two enums implement the same interface like in the example below:
public interface Fields {
}
public enum StringFields implements Fields {
A("A"),
B("B"),
C("C")
private StringFields(String str) {
this.str = str;
}
private final String str;
}
public enum BooleanFields implements Fields {
D(true),
E(false);
private BooleanFields(boolean val) {
this.val = val;
}
private final boolean val;
}
You can have two different constructors in the enum, but that means you need to have two fields (with one of them not being set). I do not think this would make much sense.
public enum Fields {
a("A"), b("B"), c("C"), d(true), e(false);
Fields(String str) {
strval = str;
value = false;
}
Fields(boolean val) {
strval = null;
value = val;
}
private final String strval;
private final boolean value;
}
EDITED*** Compiles now. You have to initialize both at the same time.
I'm developing an application for Android, and at one point the user chooses a region, after which the contents of all parts of the app is changed. Therefore I need to access an integer throughout the program. I have considered a singleton class, but I can't figure out how to add just an int, a get() and a set() to it (I want to be able to read everywhere and write in two classes(everywhere is fine)).
Should I simply declare it global?
This is what I've got going now, is it ok?
public enum Region {
INSTANCE;
private int rID =0;
public void setRID(int rID) {
this.rID=rID;
}
public int getRID()
{
return rID;
}
}
To be accessed with
Region.INSTANCE.setRID(5);
Try something like
public class State
{
static State instance = new State ();
public static State getInstance() { return instance; }
private int value;
public void setValue (int value) { this.value = value; }
public int getValue () { return value; }
}
Don't forget to store your value when your application exits, and restore it when it reloads.
This is not really a Singleton, but a static class. A class that contains a static field (a field not bounded to an instance):
public class StaticClass {
private static int value;
private Singleton () {}
public static int getValue () {
return value;
}
public static void setValue (int val) {
value = val;
}
}
you can access the value by StaticClass.getValue() and set the value by StaticClass.getValue(4). ('StaticClass must not be replaced by an object).
The private constructor prevents one to create an instance by accident.
Create a public static class and declare the setter and getter as public.
I went with an enum:
public enum Region {
INSTANCE;
private int rID =0;
public void setRID(int rID)
{
this.rID=rID;
}
public int getRID()
{
return rID;
}
}
Which I access with
Region.INSTANCE.getRID();