Constant names should be match with this regular expression '^[A-Z][A-Z0-9](_[A-Z0-9]+)$' But I have DateConstant and I think date formats of constants more understandable and readable, if use write them like this:
public static final String DATE_FORMAT_yyyyMMdd = "yyyyMMdd";
public static final String DATE_FORMAT_yyyy_MM_dd = "yyyy-MM-dd";
public static final String DATE_FORMAT_yyyy_MM_dd_Combined = "yyyyMMddHHmm";
public static final String DATE_FORMAT_yyyy_MM_dd_HH_mm = "yyyy-MM-dd HH:mm";
public static final String DATE_FORMAT_dd_MM_yyyy = "dd-MM-yyyy";
public static final String DATE_FORMAT_dd_MM_yyyy_WITH_DOT = "dd.MM.yyyy";
public static final String DATE_FORMAT_mm_dd_yyyy_WITH_SLASH = "MM/dd/yyyy";
public static final String DATE_FORMAT_m_d_yyyy_WITH_SLASH = "M/d/yyyy";
public static final String DATE_FORMAT_dd_mm_yyyy_WITH_SLASH = "dd/MM/yyyy";
public static final String DATE_FORMAT_dd_MMM = "ddMMM";
public static final String DATE_FORMAT_dd_MM_yy = "ddMMyy";
public static final String DATE_FORMAT_dd_MMM_yyyy = "ddMMMyyyy";
public static final String DATE_FORMAT_dd_MM_yyyy_COMBINED = "ddMMyyyy";
public static final String DATE_FORMAT_dd_MM_yyyy_HH_mm_ss = "yyyy-MM-dd'T'HH:mm:ss";
public static final String DATE_FORMAT_dd_MM_yyyy_HH_mm_ss_sz = "yyyy-MM-dd'T'HH:mm:ss.SSS";
public static final String DATE_FORMAT_dd_MM_yyyy_HH_mm_ss_sz_XXX = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"; // with mobile client
public static final String DATE_FORMAT_dd_MM_yyyy_HH_mm = "dd-MM-yyyy HH:mm";
public static final String DATE_FORMAT_HH_mm = "HH:mm";
public static final String DATE_FORMAT_YYYY_MM_DDTHH_mm_ssZ = "YYYY-MM-DD'T'HH:mm:ssZ"; // Google Calendar Format
I need some advice and find alternative way to rename these constant names.
I completely agree with #luk2302, including the value of a constant in its name is a bad idea.
However, given your current situation why not just define Map that is static and final. It is almost equivalent to all your constants defined and you wouldn't get any warnings from your IDE or tools like sonar.
In this solution we create 2 maps. The first map contains all the constant values but is defined as private. If this is declared public then its values can be altered and defeats the purpose of a constant. To overcome this issue we define an unmodifiable map which is declared in the last line of the static block. Now by exposing only this map no mutation on it is possible.
Try :
public class Constant {
private Constant() { } // Can't create obj of this class
// map that contains the constans but not exposed
private static final Map<String, String> mapOfConstants = new HashMap<String, String>();
// unmodifiable map that is exposed
public static Map<String, String> unmodifiableMap;
static {
mapOfConstants.put("yyyyMMdd", "yyyyMMdd");
mapOfConstants.put("yyyy_MM_dd", "yyyy-MM-dd");
mapOfConstants.put("yyyy_MM_dd_Combined", "yyyyMMddHHmm");
mapOfConstants.put("yyyy_MM_dd_HH_mm", "yyyy-MM-dd HH:mm");
mapOfConstants.put("dd_MM_yyyy", "dd-MM-yyyy");
mapOfConstants.put("dd_MM_yyyy_WITH_DOT", "dd.MM.yyyy");
mapOfConstants.put("mm_dd_yyyy_WITH_SLASH", "MM/dd/yyyy");
mapOfConstants.put("m_d_yyyy_WITH_SLASH", "M/d/yyyy");
mapOfConstants.put("dd_mm_yyyy_WITH_SLASH", "dd/MM/yyyy");
mapOfConstants.put("dd_MMM", "ddMMM");
mapOfConstants.put("dd_MM_yy", "ddMMyy");
mapOfConstants.put("dd_MMM_yyyy", "ddMMMyyyy");
mapOfConstants.put("dd_MM_yyyy_COMBINED", "ddMMyyyy");
mapOfConstants.put("dd_MM_yyyy_HH_mm_ss", "yyyy-MM-dd'T'HH:mm:ss");
mapOfConstants.put("dd_MM_yyyy_HH_mm_ss_sz", "yyyy-MM-dd'T'HH:mm:ss.SSS");
mapOfConstants.put("dd_MM_yyyy_HH_mm_ss_sz_XXX", "yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
mapOfConstants.put("dd_MM_yyyy_HH_mm", "dd-MM-yyyy HH:mm");
mapOfConstants.put("HH_mm", "HH:mm");
mapOfConstants.put("YYYY_MM_DDTHH_mm_ssZ", "YYYY-MM-DD'T'HH:mm:ssZ");
// observe this line
unmodifiableMap = Collections.unmodifiableMap(mapOfConstants);
}
}
Now you can use it in another class like :
public class Test {
public static void main(String[] args) {
Constant.unmodifiableMap.get("dd_MM_yyyy_COMBINED");
// this wouldn't execute
Constant.unmodifiableMap.put("asd", "asdad");
}
}
You won't be able to use an enum either as it would ask you to define the constants as per your question.
Related
I'm Working in A new Project and I already coded config.java for my project
My config.java code
package com.egf.myapp;
public class Config {
public static final String APP_API_URL = "http://www.egypt-freelancers.me/en/index.php";
public static final String APP_IMAGES_URL = "http://www.egypt-freelancers.me/uploads/";
public static final String APP_IMAGES_THUMB_URL = "http://www.egypt-freelancers.me/uploads/thumbnail/";
public static final String LANGUAGE_EN = "en";
public static final String LANGUAGE_AR = "fr";
public static final String DEFAULT_LANGUAGE = LANGUAGE_EN;
how to replace APP_API_URL with
custom language string.xml value
For English
http://www.egypt-freelancers.me/en/index.php
For French
http://www.egypt-freelancers.me/fr/index.php
Thanks
As per my understandings on the question you gave,
To get those variable values you can use this.
Config.STRING_VARIABLE_NAME; // this will return you the value from that class and object creation for that class is not needed as the variable is static.
Example :
String myvalue = Config.APP_API_URL;
I am using a class with only static variables to store all constants and run-time properties. But, recently I have seen instances when I'm referencing these variables, I get null.
Following is my class definition:
public class PlayerProperties {
// Runtime but constant properties
public static int screenHeight;
public static int screenWidth;
public static String androidId;
// Static properties
// Urls
public static final String baseUrl = "http://www.blynq.in/api/player/";
public static final String registerUrlAppender = "activationKeyValid";
public static final String schedulesUrlAppender = "getScreenData";
public static final String updateUrlAppender = "updateAvailable";
public static final String tokenRegisterUrl = "fcmRegister";
public static final String mediaStatsUrl = "mediaStats";
public static final String logsUrl = "logs";
public static final String pingUrl = "ping";
public static final String screenInfoUrl = "screenInfo";
// Developer Keys
public static final String youtubeDeveloperKey = "ABCDEFGH...";
// Folder structure
public static final String mediaFolder = "player/media";
public static final String imagesFolder = "player/media/images";
public static final String videosFolder = "player/media/videos";
public static final String pdfFolder = "player/media/pdf";
public static final String gifFolder = "player/media/gif";
public static final String webFolder = "player/media/web";
public static final String othersFolder = "player/media/others";
public static final String logsFolder = "player/logs";
public static final String defaultFolder = "player/default/";
public static final String serFolder = "player/ser/";
public static final String tempFolder = "player/temp/";
// Shared Prefs Keys
public static final String ANDROID_ID_KEY = "ANDROID_ID";
public static final String MY_PREFERENCES_KEY = "MyPrefs";
// General properties
public static final String dateTimeFormatString = "ddMMyyyyHHmmss";
public static final String dateFormatString = "yyyy-MM-dd";
// Timeouts
public static final int httpPollTimeout = 20000; // in millis
public static final int pingPeriodicity = 30; // in secs
public static final int updateCheckPeriodicity = 24; // in hrs
public static final int pushEnabledPollPeriodicity = 30; // in secs
public static final int pushDisabledPollPeriodicity = 30; // in secs
public static final int statsUploadPeriodicity = 60; // in mins
public static final int logsUploadPeriodicity = 24; // in hours
public static final int cleanupPeriodicity = 24; // in hours
public static final int registrationStatusRecheckPeriod = 20000; // in millis
public static final int tokenResendToServerPeriod = 20000; // in millis
// Others
public static final int maxTextHeight = 50; // in dp
...
}
I have not stored any reference instantiatin PlayerProperties class, as all variables contained within are static.
When I am referencing the variable androidId using PlayerProperties.androidId , I SOMETIMES get null.
I have initialized the variable in one of the activities:
PlayerProperties.androidId = sharedpreferences.getString(PlayerProperties.ANDROID_ID_KEY, String.valueOf(UUID.randomUUID()));
My suspicion is that garbage collector was kicked by android in between. If gc does kick in, would it knock off all my runtime-initialized static variables ?
Which memory segment are the static variables stored ?
If not, what else could be the issue ?
Extra details: My app is configured to automatically launches on boot. I am facing the above described issue only with low end processors and when app is automatically triggered on boot.
Please note the following in reference to above question:
Garbage collector removes only unreferenced objects. Static variables will lose their values only when they are unloaded from JVM during run-time.
Initialization happens when app is launched via activities. If there are any services/broadcast receivers that are accessing methods within other classes and use these ids, and the app is not yet running by that time, the uninitialized values are referenced as default value. In case of string - it is null.
Nothing to do with low-end processors, easy to blame them often but JVM is powerful enough.
Only public static String androidId; can be null, when you want to use it you should init it in this class or in some other class in onResume()
androidId is a reference to an string, string is a class that will get by default a null reference as intial value if you dont do it....
look at this taken from oracle's doc
So basically androidId is null because is not initialized....the fact that the variable is static or not is not relevant in this case...
see here for more details
...I SOMETIMES get null.
yes, you will get always null unless its value change at run time...
is there a possibility to activate autocomplete for constants with underscores _?
I have a class with many constants, where many of them begin same. Example:
// Component details
public static final String PROPERTY_NAME_COMPONENT_MATERIAL_NUMBER = "name";
public static final String PROPERTY_NAME_COMPONENT_OVERALL_WORK_STATUS = "componentOverallWorkStatus";
public static final String PROPERTY_NAME_COMPONENT_RELEASE_STATUS = "freigabestatus";
public static final String PROPERTY_NAME_COMPONENT_DESCRIPTION = "label";
public static final String PROPERTY_NAME_COMPONENT_AMOUNT = "newAmount";
public static final String PROPERTY_NAME_COMPONENT_BASE_QUANTITY_UNIT = "basismengeneinheit";
public static final String PROPERTY_NAME_COMPONENT_PRODUCER = "hersteller";
public static final String PROPERTY_NAME_COMPONENT_PRODUCER_FRAGMENT_NUMBER = "herstellerteilenummer";
public static final String PROPERTY_NAME_COMPONENT_EXCLUDE_ALTERNATIVE_ARTICLE = "componentExcludeAlternativeArticle";
public static final String PROPERTY_NAME_COMPONENT_GENERAL_INFO = "componentGeneralInfo";
They all start with PROPERTY_NAME_COMPONENT and if I now begin to type this
System.out.println(ClassWithThoseConstants.P
and press Ctrl + Space. Now I got all constansts starting with P, which is fine. But now I'd like to go further with camelcase style, i.e. PNCP which shall lead to the options:
PROPERTY_NAME_COMPONENT_PRODUCER and PROPERTY_NAME_COMPONENT_PRODUCER_FRAGMENT_NUMBER.
Typing P_N_C_P doesn't help either. Is there a possibility? I couldn't find any.
I would know what is the best practice for storing global constants which can change with the environnement (debug, preprod, prod, release, etc) at compile time.
In iOS, I used to keep all global constants in a header file and change it with pre-processor macro see this answer:
Where to store global constants in an iOS application?
What solution should I use for Android ?
Create a class constants in your base package folder. (or create an interface instead of a class so there is no need to reference the class everytime, however this is bad practice due to code readability, but it will work)
Fill it with public static final values.
Moreover, both the class as well as the interface can also be declared as abstract.
If values for your constants depend on environment (density, locale etc.) then you should use resources for storing them (integer, string, dimen etc.).
In another case you can put your global constants in one file (best practices - use prefixes for every set of constants) or put local constants in related classes (for instance, Intent holds flags. extras, categories and so on).
Use public static final values. and keep them in separate java file as follows:
static String QC = "http:/************";
static String DEV = "http:/************";
static String CLOUD = "http:/************";
static String SERVICEURL = CLOUD ; //Use this SERVICEURL in your code at run time
Another solution might be to use the resource file (if you are content with storing only string values).
This could be used to store constants such as the account that this application manages:
Ex. WelcomeActivity.java
AccountManager am = AccountManager.get(WelcomeActivity.this);
Account account = am.getAccountsByType(getResources().getString(R.string.ACCOUNT_TYPE))[0];
Ex. res/values/strings.xml
<resources>
<string name="ACCOUNT_NAME">com.acme.MyAccountSignature</string>
</resources>
This would also allow you to modify this without the need to recompile (similarly to how you would normally decouple translations, which the strings.xml file is best used for).
Pretty simple solutions is here
public class Constants {
/**
* Object key prams when pass the json object from server.
*/
public static final String KEY_EMAIL = "email";
public static final String KEY_PASSWORD = "password";
public static final String KEY_DEVICE_TOKEN = "device_token";
public static final String KEY_DEVICE_TYPE = "device_type";
public static final String KEY_NAME = "name";
public static final String KEY_COUNTRY_CODE = "country_code";
public static final String KEY_PHONE_CODE = "phone-code";
public static final String KEY_GENDER = "gender";
public static final String KEY_DATE_OF_BIRTH = "date_of_birth";
public static final String KEY_USER_ID = "user_id";
public static final String KEY_LIMIT = "limit";
public static final String KEY_DRIVER_ID = "driver_id";
public static final String KEY_LONGTITUDE = "logitude";
public static final String KEY_LATTITUDE = "lattitude";
public static final String KEY_RATING = "rating";
public static final String KEY_DETAILS = "details";
public static final String KEY_ACCESS_TOKEN= "access_token";
/**
* Fragments name
*/
public static final String FRAG_ETA = "ETA";
public static final String FRAG_ACCOUNT_FRAGMENT = "ACCOUNT_FRAGMENT";
public static final String FRAG_SETTING_FRAGMENT = "SETTING_FRAGMENT";
public static final String FRAG_MAP_FRAGMENT = "MAP_FRAGMENT";
public static final String FRAG_FEEDBACK = "FEEDBACK";
public static final String FRAG_RATE_FRAGMENT = "RATE_FRAGMENT";
public static final String USA_CODE = "+1";
public static final String DISTANCE_SEARCH = "DISTANCE_SEARCH";
}
happy coding
Property File
We store a property file under <project>/<package>/src/main/assets/config.properties
Loading properties
private static final String PROPS_NAME = "config.properties";
private static Properties configuration;
...
public static void init(Context ctx) {
configuration = new Properties();
InputStream rawResource = resources.getAssets().open(PROPS_NAME);
configuration.load(rawResource);
I have the folowing interface;
public static interface Attributes
{
public final static String InterestDeterminationDate = "InterestDeterminationDate";
public final static String CreditType = "CreditType";
public final static String NumberInternal = "NumberInternal";
public final static String InterestRate = "InterestRate";
public final static String RemainingDebtAmount = "RemainingDebtAmount";
public final static String ConsumerPart = "ConsumerPart";
public final static String TechnicalProductName = "TechnicalProductName";
public final static String TermOfDuration = "TermOfDuration";
public final static String PeriodInterestTaxReduction = "PeriodInterestTaxReduction";
public final static String OriginMark = "OriginMark";
public final static String Currency = "Currency";
public final static String PenaltyRuleId = "PenaltyRuleId";
public final static String InstallmentCalculationMethod = "InstallmentCalculationMethod";
public final static String InterestRenewalDate = "InterestRenewalDate";
public final static String TechnicalProductDescription = "TechnicalProductDescription";
public final static String TechnicalProductDate = "TechnicalProductDate";
public final static String CollectionIntervalPeriod = "CollectionIntervalPeriod";
public final static String Enddate = "Enddate";
}
I need to check is a given string is a part of this Attributes Interface.
How can i check this?
Regards,
bas Hendriks
If you really want todo this, then you should use reflection and go through all the values in Attributes.
A better way to do this would be the use of enums :
public enum Attributes{
InterestDeterminationDate,
CreditType,
NumberInternal,
InterestRate,
RemainingDebtAmount,
ConsumerPart,
TechnicalProductName,
TermOfDuration,
PeriodInterestTaxReduction,
OriginMark,
Currency,
PenaltyRuleId,
InstallmentCalculationMethod,
InterestRenewalDate,
TechnicalProductDescription,
TechnicalProductDate,
CollectionIntervalPeriod,
Enddate;
}
and the Attributes.valueOf(yourVariable); would check this for you.
Beware with enum, the valueOf() method will throw a IllegalArgumentException if yourVariable isn't in Attributes. Plus you yourVariable isn't null or you will have to handle a NullPointerException
Your question doesn't make it clear whether you're trying to find out if the query string is the property name or value. If you're trying to find out if it's a value, the following will work:
public static boolean hasValue(String value) throws IllegalAccessException {
for(Field field : Attributes.class.getDeclaredFields()) {
if(((String)field.get(Attributes.class)).equals(value)) {
return true;
}
}
return false;
}
However, I would advise following Colin's suggestion of using an Enum, it will be easier for you to work with in the future.
You can build a set using reflection and test against that set:
Class<Attributes> attr = Attributes.class;
Field[] fields = attr.getDeclaredFields();
final Set<String> fieldsInAttributes = new HashSet<String>();
for (Field field : fields) {
fieldsInAttributes.add(field.getName());
}
System.out.println(fieldsInAttributes.contains("PenaltyRuleId"));
You can use the reflection API, and the "getFields()" method of the Class class.
Then you check the field name with the "getName()" method of the Field class.
Here is the Oracle official tutorial.
public static String getFieldName(String fieldValue) throws Exception {
for (Field field : Attributes.class.getFields())
if (fieldValue.equals(field.get(null)))
return field.getName();
return null;
}