I have a question about the following code:
public Class Settings{
public static final String WelcomeMessage= "helloworld";
public static final String ByeMessage= "yo";
public static String[] widgets = {WelcomeMessage,ByeMessage};
}
The compiler complains about duplicat variables. Can I delete the 2 separate variables and still acces WelcomeMessage by Settings.WelcomeMessage? I don't need to acces it by Settings.widget[0]? And is it possible to add another variable to the WelcomeMessage variable (by for instance using a static hashtable)?
Edit: I know this code doesn't look right but it's just an example because I wondered why the compiler thinks WelcomeMessage (as a separata variable) is the same as the variable in the Widgets array.
I would consider java-enums in your case:
public enum Settings {
WelcomeMessage ("helloworld"),
ByeMessage ("yo");
public final String value;
Settings(String value) {
this.value = value;
}
}
You can access now the values via Settings.WelcomeMessage.value. Also you get a List of the enums with Settings.values().
You've marked the fields as public static which means that yes you'll be able to access them via:
Settings.WelcomeMessage
or if you you use a static import in your class, just:
WelcomeMessage
You haven't actually used these constants in the widgets array, you've just created two new strings in there "WelcomeMessage" and "ByeMessage"
public static String[] widgets = {"WelcomeMessage","ByeMessage"};
No, if you delete the WelcomeMessage and ByeMessage constants you can't access them in that way, you'd have to go through the widgets array and access them as:
Settings.widgets[0]
I think you meant to use this instead:
public Class Settings
{
public static final String WelcomeMessage= "helloworld";
public static final String ByeMessage= "yo";
public static String[] widgets = {WelcomeMessage,ByeMessage};
}
But this is better:
public Class Settings
{
public static String[] widgets = {"WelcomeMessage","ByeMessage"};
}
And yes you can access WelcomeMessage via Settings.widgets[0].
Edit: Oops - yep - of course you cannot access them by name, only index into the array.
Edit 2: If you make the field protected or private and provide 'getter' methods, then it doesn't matter to any user classes how they are implemented:
public Class Settings
{
private static final String welcomeMessage= "helloworld";
private static final String byeMessage= "yo";
public static String getWelcomeMessage()
{
return welcomeMessage;
}
public static String getByeMessage()
{
return byeMessage;
}
}
Related
How can I set or get a field in a class whose name is dynamic and stored in a string variable?
public class Test {
public String a1;
public String a2;
public Test(String key) {
this.key = 'found'; <--- error
}
}
You have to use reflection:
Use Class.getField() to get a Field reference. If it's not public you'll need to call Class.getDeclaredField() instead
Use AccessibleObject.setAccessible to gain access to the field if it's not public
Use Field.set() to set the value, or one of the similarly-named methods if it's a primitive
Here's an example which deals with the simple case of a public field. A nicer alternative would be to use properties, if possible.
import java.lang.reflect.Field;
class DataObject
{
// I don't like public fields; this is *solely*
// to make it easier to demonstrate
public String foo;
}
public class Test
{
public static void main(String[] args)
// Declaring that a method throws Exception is
// likewise usually a bad idea; consider the
// various failure cases carefully
throws Exception
{
Field field = DataObject.class.getField("foo");
DataObject o = new DataObject();
field.set(o, "new value");
System.out.println(o.foo);
}
}
Class<?> actualClass=actual.getClass();
Field f=actualClass.getDeclaredField("name");
The above code would suffice .
object.class.getField("foo");
Unfortunately the above code didn't work for me , since the class had empty field array.
How can I set or get a field in a class whose name is dynamic and stored in a string variable?
public class Test {
public String a1;
public String a2;
public Test(String key) {
this.key = 'found'; <--- error
}
}
You have to use reflection:
Use Class.getField() to get a Field reference. If it's not public you'll need to call Class.getDeclaredField() instead
Use AccessibleObject.setAccessible to gain access to the field if it's not public
Use Field.set() to set the value, or one of the similarly-named methods if it's a primitive
Here's an example which deals with the simple case of a public field. A nicer alternative would be to use properties, if possible.
import java.lang.reflect.Field;
class DataObject
{
// I don't like public fields; this is *solely*
// to make it easier to demonstrate
public String foo;
}
public class Test
{
public static void main(String[] args)
// Declaring that a method throws Exception is
// likewise usually a bad idea; consider the
// various failure cases carefully
throws Exception
{
Field field = DataObject.class.getField("foo");
DataObject o = new DataObject();
field.set(o, "new value");
System.out.println(o.foo);
}
}
Class<?> actualClass=actual.getClass();
Field f=actualClass.getDeclaredField("name");
The above code would suffice .
object.class.getField("foo");
Unfortunately the above code didn't work for me , since the class had empty field array.
public final class Templates {
public static class NewDeviceDetailsConsts {
public static final String AAA = "aaaa";
public static final String BBB = "bbbb";
public static final String CCC = "cccc";
}
}
for using AAA, I have to write Templates.NewDeviceDetailsConsts.AAA and thats a long string to use 10-20 times in every class I use it.
Will it be efficient to use it like,
I define a field in classes I need it , Templates.NewDeviceDetailsConsts DeviceConst; and use DeviceConst.___ in the class.
Is it fine or can I do it better than that.
There a a few ways you can solve this problem.
create a static import:
Where your import statements are, add this import static path.to.Templates.NewDeviceDetailsConsts.AAA;. This will allow you to reference your AAA object just by typing AAA.
Unfortunately, you will have to add this line at the top of all your classes.
Create a getter your Templates class.
public static NewDeviceDetailsConsts getAAA(){
return NewDeviceDetailsConsts.AAA;
}
Then use Templates.getAAA() to get the AAA object.
Save a reference to the AAA object inside the working class.
private static NewDeviceDetailsConsts AAA = Templates.NewDeviceDetailsConsts.AAA;
I would use enum's for such purpose:
public final class Templates {
public enum NewDeviceDetailsConsts {
AAA("aaaa"), BBB("bbbb"), CCC("cccc");
private String value;
private NewDeviceDetailsConsts(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
}
Then you can use the constants as follows:
NewDeviceDetailsConsts aaa = NewDeviceDetailsConsts.AAA;
You can also use AAA, BBB, ... without param if you need as follows:
public final class Templates {
public enum NewDeviceDetailsConsts {
AAAA, BBBB, CCCC;
}
}
And lastly, you should not define them inside a class. An enum can also be a top level class as follows unless they have to be part of a class:
public enum NewDeviceDetailsConsts {
AAAA, BBBB, CCCC;
}
I have a REST API test suite where certain URIs are used repeatedly. Thus, I created a separate class with public static final members. Something like:
public class RestURI {
public RestURI(){}
public static final String getAllShipsURI = "/ship/manager/ships";
public static final String getAllPortsURI = "/port/manager/ports";
}
However, is there a way to deal with URIs like this:
/infrastructure/ships/docked/" + shipId + "/capacity
I am looking for a way such that I can declare the URL like above in the RestURI class and still specify values in the test when I use them.
You can use a constant format, rather than a String and use a static getter:
public static String getShipUri(int shipId) {
return String.format("/infrastructure/ships/docked/%d/capacity", shipId);
}
You could use String.format. Like this:
public class RestURI {
public RestURI(){}
public xxx() {
int shipId = 219001000;
... String.format(dockedShipURIFormat, shipId) ...;
}
public static final String dockedShipURIFormat = "/infrastructure/ships/docked/%d/capacity";
}
I've used ANTLR StringTemplate for exactly this on multiple occasions. The ability to have inline macro parsing and a little if..else logic in the templates is pretty powerful, and it maintains good readability.
Is there a way to set the ID of a string in code, so I can call the string in other Activities by R.strings.codegenstring. I can't predefine them in the string.xml since there will be a variable amount of code generated strings.
No. But you can define a String as static
public class A {
public static String s;
public void yourStringGeneratingFunction() {
s = "blahblah";
}
}
And access it from another class by:
A.s
No, there no way. To call string by R.string.codegenstring you must define public static string variable in R class. But R class are built by Android during compiling and you shouldn't modify it.