I am pretty new in Android and I do not know how is the proper way to manage static constants. I mean, I need to use several constants (such as COMMAND_BACK = 100) in several Java classes and activities. It is not beautiful to declare them as attributes in each single activity so, what is the correct way to do this?
I though about declaring them in strings.xml, but it does not seem suitable neither...
Thanks in advance.
You can make a class like this :
public final class AppConstants {
//put all the constant here
// Eg :
public static final int SPLASH_TIME = 1000;
}
The disadvantage by declaring it in a resource.xml file is that you need a context to receive the value. This is fine as long as you need those values inside a context class otherwise you have to pass one around.
The elegant solution would be extending the Application class since the android os itself uses static fields that way.
Declare
public final class ConstantClass {
public final static int COMMAND_BACK = 100;
}
Usage
int num = ConstantClass.COMMAND_BACK;
Add a Constants class to the project
public class Constants {
public static final String STRING1 = "First String";
public static final String STRING2 = "Second String";
public static final int INTEGER1 = 1;
public static final float FLOAT1 = 0.1f;
}
// Use
textView.setText(Constants.STRING1);
Create a common interface where you can declare all the constants.Constants can further be grouped here to make it mode clean.
public interface Constants {
public interface XYZ{
public static final int A= 1;
public static final int B= 2;
}
public interface REPORT_TYPE_FLAGS{
public static final String C= "0";
public static final String D= "1";
}
}
Another elegant way is to define a constant class with other inner subclasses
`private final class Constant {
public static class TypeOne {
public static final String NAME = "Type 1";
public static final int CODE = 1;
}
public static class TypeTwo {
public static final String NAME = "Type 2";
public static final int CODE = 2;
}
}
`
And you can access it in this way
`String typeOneName = Constant.TypeOne.NAME;
int typeTwoCode = Constant.TypeTwo.CODE;
`
Related
I need to pass a class variable to an enum while initializing it .But the class variable is not accessible while initializing the enum . So how can this be achieved ?
I tried passing variable of another class, same class where the enum resides . Both didn't work.
public class ComponentConstants {
public Constants constants = Constants.getInstance();
enum FIELDS_RESOURCES {
//instead of text i want to use constants.data_type.text. But I was not able to.
SourcetType(true, "text", "Source Type", "source_type", 255, false); //No I18N
private VOCFIELDS_RESOURCES(boolean isCustomField, String data_type, String field_label, String api_name, int length, boolean isVisible) {
this.isCustomField = isCustomField;
this.data_type = data_type;
this.field_label = field_label;
this.api_name = api_name;
this.length = length;
this.isVisible = isVisible;
}
}
}
In the above I want to use the value from constants since if there is any change there ,it should be reflected in my code too . Single point of constants , but i was not able to use it. How can this be achieved and why is it not allowing to use other variables? Thanks!
public class Main {
public enum Enumeration {
Test(Constants.a, Constants.b); // can refer to constant "a" & "b" static variables
private final String a;
private final String b;
Enumeration(String a, String b) {
this.a = a;
this.b = b;
}
}
public static class Constants {
static String a = "a";
static String b = "b";
}
}
If you utilize static fields as constants, they can be referenced within enumeration constructors. More details here regarding enum fields.
In the program I am making, I am trying to get a formatted season name for a given season(formatted so it . I keep the formatted names in an interface, since if I were to use a map, it would be unnecessarily regenerated, since I don't make an instance of TeamBuilder
The Seasons interface:
public interface Seasons {
/*
* Contains a formatted list of seasons.
*
* An interface is being used as an alternative to using a Map in the
* TeamBuilder class, since calling parseTeam would have to build
* mappings for the seasons each time it
* was called. This way, the formatted name can simply be grabbed
*/
final String Skyrise = "Skyrise";
final String Toss_Up = "Toss%20Up";
final String Sack_Attack = "Sack%20Attack";
final String GateWay = "Gateway";
final String Round_Up = "Round%20Up";
final String Clean_Sweep = "Clean%20Sweep";
final String Elevation = "Elevation";
final String Bridge_Battle = "Bridge%20Battle";
final String Nothing_But_Net = "Nothing%20But%20Net";
final String Starstruck = "Starstruck";
final String In_The_Zone = "In%20The%20Zone";
final String Turning_Point = "Turning%20Point";
}
The problem comes when I try to grab these seasons. My TeamBuilder class takes in an argument(String season), which is unformatted. My question is, is there any way that I can use a String argument for a method to get a specific item from an interface? This is the most preferable to using a HashMap, which would needlessly regenerate the same information
All these classes can be found on the Github page for this project.
If you want to do it in a typed way, you can use Enum for this:
enum Season{
Skyrise,Toss_Up, Sack_Attack;
#Override
public String toString() {
switch(this){
case Skyrise: return "Skyrise";
case Toss_Up: return "Toss%20Up";
case Sack_Attack: return "Sack_Attack";
default: return "";
}
}
}
public class main{
public static void printSeason(Seasons seasons){
System.out.println(seasons);
}
public static void main(String[] args) {
Seasons e = Seasons.Skyrise;
printSeason(e);
System.out.println(e);
}
}
Since the compiler internally invokes the toString(), you can pass the argument as a Seasons or a String like my example.
And if you still want to use a map without "unnecessarily regenerated" you can use a static field with static initializer like this:
class Seasons {
private static Map<String,String> map = new HashMap<>();
static {
map.put("Skyrise", "Skyrise");
map.put("Toss_Up", "Toss%20Up");
}
public static String getFormatted(String key){
return map.getOrDefault(key,"");
}
}
class main{
public static void main(String[] args) {
System.out.println(Seasons.getFormatted("Skyrise"));
}
}
Just to integrate on Snoob answer you can have enum with fields, so:
enum Season
{
Skyrise("Skyrise"),
Toss_Up("Toss%20Up"),
Sack_Attack("Sack%20Attack")
;
public final String fancyName;
private Season(String fancyName)
{
this.fancyName = fancyName;
}
}
You really have all the benefits without any drawback.
I've got only a main class in my small program and it's using a lot of path.
As they will not change while the program is running, I think I can put static in their declaration but not sure for the final. Moreover, I'm not sure where is the best place to declare my paths. Is it in the main class or just before?
Here's an example of my code:
package classtest;
public class ClassTest {
// Should I put the path here?
public static void main(String[] args) {
String dirPath = "C:/Users/test1/";
String pathOut = "C:/Users/stats.csv";
// or here?
}
}
An alternative approach is reading your paths from a Properties file:
Properties prop = new Properties();
And use the properties wherever you would like. It makes refactoring later very easy:
prop.getProperty("diPath");
prop.getProperty("pathOut");
It is more common to make your paths arguments, so they can be set by the person running the program.
public class ClassTest {
public static void main(String[] args) {
if (args.length < 2) {
System.err.println("Usage: java ClassTest {dir} {output}");
return;
}
String dirPath = args[0];
String pathOut = args[1];
}
}
final keyword means that the value will never reassigned.
static keyword let the variable be a class variable instead of instance variable.
An additional note, generally class constants are written in uppercase with underscore delimiter, so I changed the names.
So if you like to declare them "globally" the best is to use a code similar to the following.
public class ClassTest {
public static final String DIR_PATH = "C:/Users/test1/";
public static final String PATH_OUT = "C:/Users/stats.csv";
public static void main(String[] args) {
// Use DIR_PATH or PATH_OUT as needed
}
}
Note that the previous code is useful only if you reuse the DIR_PATH or PATH_OUT variables in different methods. Otherwise defining the variable local to the main method is correct to limit the visibility to the only portion of code using it.
You can do this kind of refactoring:
public class ClassTest {
// Specify a base path for all paths to be used
public static final String BASE_PATH = "C:/Users";
// 1. If these paths will be used in several methods, declare them here
public static final String dirPath = BASE_PATH + "/test1/";
public static final String pathOut = BASE_PATH + "/stats.csv";
public static void main(String[] args) {
// 2. If those paths will be used in the main method only, declare them here
final String dirPath = BASE_PATH + "/test1/";
final String pathOut = BASE_PATH + "/stats.csv";
}
}
Static members of a class should be declared outside the scope of any class method.
Try this .. It's the cleanest way :
public class ClassTest implements StaticPath {
public static void main(String[] args) {
System.out.print(PATH_OUT);
}
}
interface StaticPath {
public final static String PATH = "C:/Users/";
public final static String PATH_OUT = PATH + "stats.csv";
public final static String PATH_IN = PATH + "dyn.csv";
}
Well, I need this data to be used in at least two classes:
String navHome = "home";
String navAbout = "about";
String navUpload = "upload";
String navUploadProc = "uploadProc";
String navStartUpload = "startUpload";
String navContact = "contact";
String navSearch = "search";
String navManual = "manual";
String navBackToGmis = "backToGmis";
I was thinking of just pasting that into other classes, but then it violates the principles of programming, since it's repeating the same thing. Text and XML files are not comfortable to store data, inheritance isn't an option, since Java doesn't support multiple inheritance... Any ideas?
Yeah, I know it will sound retarded to most of you, but I need tipps on this.
If these are constants, then you can declare them in one class (or interface) and use them in another:
A.java:
public class A {
public static final String navHome = "home";
public static final String navAbout = "about";
public static final String navUpload = "upload";
public static final String navUploadProc = "uploadProc";
public static final String navStartUpload = "startUpload";
public static final String navContact = "contact";
public static final String navSearch = "search";
public static final String navManual = "manual";
public static final String navBackToGmis = "backToGmis";
. . .
}
B.java:
import static A.*; // or list each String in a separate import
public class B {
. . . // code can use nav* as if they were declared in class B
}
I have an annotation I can't change which expects two String arguments.
I'd like to use it like this:
#RequestMapping( MyUrls.FOO.a, MyUrls.FOO.b )
This is how I imagined implementing it
public enum MyUrls {
FOO("a", "b"),
BAR("c", "d");
public String a, b;
MyUrls(String a, String b) {
this.a = a;
this.b = b;
}
}
This doesn't work since a or b can't be statically resolved.
What alternatives do I have which are nicer than:
class MyUrls {
public static String FOO_A = "";
public static String FOO_B = "";
// ...
}
Although your question does not look like a question but as a declaration, I agree with you.
You cannot use enum members when you are defining annotations. Only "real" constants, i.e. static final fields and constant expressions are applicable. So, there is no good alternative right now.
You could use a static inner class to group your strings.
class MyUrls {
public static final class Foo{
public static final String A = "";
public static final String B = "";
// ...
}
}
//works as
MyUrls.Foo.A