What I want to do is access a variable stored in one class with a string.
For example I have
public class Values {
public static boolean enabled;
}
And then in a different part of the project I have the object and a string with the fields name. How do I get and set the value of the field?
If you have the name as a string, you should use reflection:
import java.lang.reflect.Field;
public class Values {
public static boolean enabled = false;
public static void main(String[] args) throws Exception {
Values v = new Values();
Field field = v.getClass().getField("enabled");
field.set( v, true );
System.out.println( field.get(v) );
}
}
Values.enabled = true;
or
Values.enabled = false;
Alternatively, you can create a static getter and setter for the Values class and call those static methods instead.
#Maricio Linhares's answer is very good; however, note that reflection is pretty slow. If you are doing this a lot you might have performance problems. An alternative might be to use a map. The code would follow as
public class Values {
public static Map<string,bool> variableMap;
public static void main(String[] args) throws Exception {
// adding a 'variable'
variableMap = new YourFavoriteMapImplementation();
variableMap.put("enabled",true);
// accessing the 'variables' value
bool val = variableMap.get("enabled");
System.out.println(val);
}
}
Related
I need to assign a value to a println statement so that i can declare it as a variable and then use it anywhere in the code. i want to be able to assign a value to the "result" in the println, however i do not know how to do this. Does anyone know how to assign a value to this so that it can be used anywhere?
I have tried the following, however i get an error saying that void cannot be converted to string...
You can define a method:
private void print(String value) {
System.out.println(value);
}
This can be called from anywhere in your class.
If you would like to re-use this functionality in different classes you could create a separate class for it:
public class Printer {
public void print(String value) {
System.out.println(value);
}
}
You can then add it as a dependency in the class that wants to print:
public class MyApp {
private Printer printer;
public MyApp(Printer printer) {
this.printer = printer;
}
public void doSomething() {
printer.print("Hello world");
}
}
You can probably write it as a JAVA lambda expression, such as:
Consumer<String> print = it-> System.out.println(it);
Whenever you want to run, you can run it like this:
print.accept("hello");
Br,
Tim
Make a Consumer and pass a object whenever you want to print taht object.
Consumer consumer= System.out::println;
consumer.accept(5);
Updated
In your case define consumer as :
public static int myHouseValue;
public static final Consumer CONSUMER= System.out::println;
and any where and in any class you can use this consumer. just include this static member. and pass the object you want to print.
CONSUMER.accept(5);
CONSUMER.accept("String");
CONSUMER.accept(new Object());
CONSUMER.accept(myHouseValue);
Your Code (Updated):
public class Weka {
public static int Lotsize;
public static int Bedrooms;
public static int LocalSchools;
public static int Age;
public static int Garages;
public static int Bathrooms;
public static double myHouseValue = 0d;// here is the default value zero
public static final Consumer CONSUMER = System.out::println;
public static void main(String[] args) throws Exception {
System.out.println("Server up and running");
. . .
your code
. . .
// donot declare myHouseValue again , its already defined wher we set it to default value. only use here
myHouseValue = (coef[0] * Lotsize) +
(coef[1] * Bedrooms) +
(coef[2] * LocalSchools) +
(coef[3] * Age) +
(coef[4] * Garages) +
(coef[5] * Bathrooms) +
coef[7];
CONSUMER.accept(myHouseValue);
How can I access my array from a different class? I have 3 classes; Main (where I want to access the array from) FramePanel (my GUI and where the value from UserInputNum is taken from) and StoryArray (where my array is saved).
I need to access the array in the nested If loop in the Main class, this is because I want too save the specific array data to a string and eventually append it into a JTextArea.
Here are the two classes needed:
Main.java
public class Main
{
public static String UserInput;
public static int UserInputNum;
public static void main(String[] args)
{
FramePanel.main();
StoryArray.main();
UserInputNum = Integer.parseInt(UserInput);
if (UserInputNum >= 0)
{
if (UserInputNum <= 399)
{
StoryArray.storyLine[UserInputNum];
}
else
{
}
}
else
{
}
}
}
StoryArray.java
public class StoryArray
{
public static String storyLine[] = null ;
public String[] getStoryLine()
{
return storyLine;
}
public static void main()
{
//String[] storyLine;
storyLine = new String[399];
storyLine[0] ("1")
storyLine[1] ("2")
storyLine[2] ("3")
storyLine[3] ("4")
storyLine[4] ("5")
storyLine[5] ("6")
In another class you can call the array like this:
String value = StoryArray.storyLine[index];
As it is a static public field you can access it directly by StoryArray.storyLine. But as you have a getter ethod I would suggest to make this getter setter static and the array field private and access it through getter method like that: StoryArray.getStoryLine() (to see why read about encapsulation).
You also shouldn't start your class (main) name from lower case, here are standard coding conventions for java language: http://www.oracle.com/technetwork/java/codeconvtoc-136057.html
Once you've called StoryArray.main(), then you should be able to do StoryArray.storyLine[/*element id*/] = "whatever you want" to get or set any element in storyLine. Additionally, you aren't defining any default array values. In StoryArray.main(), you need to have lines of the form storyLine[n] = "n".
I'm basically a beginner in Java and I am trying to figure out this problem:
my project uses (integer)constant through many classes and I need to set up this constant from file/argument of programm and I have no idea how. I could remove "final" statement but that is against all conventions.
How to resolve this? What is best way to avoid it? Please help me :)
short example:
public class App {
public static final int k;
public static void main( String[] args ) {
k = Integer.parseInt(args[0]); // does not work ... sure but how?
}
}
EDIT: public STATIC void main ... (it was missing static)
You can only use this kind of functionality within the static { } block.
I'd recommend making the constant itself private, and accessible only through public static getter methods. This should be a suitable architecture.
You need to use a static{} block:
public class App {
public static final int k;
static {
String kvalue = "";
try
{
// Insert some code to open a file and read a value from it.
kvalue = "<value from file>";
}
catch( Exception e )
{
// handle any exceptions opening the file
}
finally
{
k = Integer.parseInt( kvalue );
}
}
public static void main( final String[] args ) {
// do stuff
}
}
Alternatively, you could have each class that requires this value access to a shared pool of data, the ApplicationContext, where the value X would reside as a constant:
public final class ApplicationContext {
public static abstract class Worker {
private final ApplicationContext mApplicationContext;
public Worker(final ApplicationContext pApplicationContext) {
this.mApplicationContext = pApplicationContext;
}
public final ApplicationContext getApplicationContext() {
return this.mApplicationContext;
}
}
private final int mX;
ApplicationContext(final String[] pArgs) {
this.mX = pArgs[0];
}
public final int getX() {
return this.mX();
}
}
By having all relevant classes extend ApplicationContext.Worker, we can ensure access to the constant value without having to rely upon a static implementation because all classes will receive a reference to ApplicationContext upon construction.
It doesn't work because static final variables can only be initialized in static blocks.
I have encountered a weird problem in my app (java).
I have an enum. Something like that
public enum myEnum implement myIntrface{
valueA(1),valueb(2),valuec(3),valued(4)
private int i;
// and then - a constructor
public MyEnum(int number){
i = number;
}
private MyObj obj = new MyObj;
// getter and setter for obj
}
and in another class I have this
MyEnum.valueA.setObj(new Obj(...))
in briefe - I have an enum with a private instance member that has a set and a get.
So far so good -
The only thing that amazes me is that later on I look at the value of the MyEnum.valueA().obj is null.
there is nothing that updates the value to null, I have even gave it a default value in the constructor and I still see it null later.
any suggestions?
Enums should be un-modifiable classes so you shouldn't really be doing this. If your looking to modify the state of a type based object like an enum you should use an final class approach with embedded constants. Below is an example of a class based approach with a modifiable name an a un-modifiable name...
public final class Connection {
public static final Connection EMAIL = new Connection("email");
public static final Connection PHONE = new Connection("phone");
public static final Connection FAX = new Connection("fax");
/**/
private final String unmodifiableName; //<-- it's final
private String modifiableName;
/*
* The constructor is private so no new connections can be created outside.
*/
private Connection(String name) {
this.unmodifiableName = name;
}
public String getUnmodifiableName() {
return unmodifiableName;
}
public String getModifiableName() {
return modifiableName;
}
public void setModifiableName(String modifiableName) {
this.modifiableName = modifiableName;
}
}
The purpose of enums is to represent constant values. It does not make any sense to set the fields of a constant value.
You should declare your fields as final, and use the constructor to initialize all of them.
For reference, the following code works as expected:
public class Test {
public static enum MyEnum {
valueA(1),valueb(2),valuec(3),valued(4);
private int i;
private Object o;
private MyEnum(int number) {
i = number;
}
public void set(Object o) {
this.o = o;
}
public Object get() {
return o;
}
}
public static void main(String[] args) {
System.out.println(MyEnum.valueA.get()); // prints "null"
MyEnum.valueA.set(new Integer(42));
System.out.println(MyEnum.valueA.get()); // prints "42"
}
}
the cause of this problem is the db40 framework . It loads an enum from the db using reflection. This is well documented .
http://developer.db4o.com/Forums/tabid/98/aft/5439/Default.aspx
I am creating a helper class in parsing XML elements, so the developer do not need to know the exact name and capitalization of the XML fields.
private static class TagNames{
public static String RESOURCE_ID = "ResourceId";
public static String RESOURCE_NAME = "ResourceName";
public static String RESOURCE_PRICE = "ResourcePrice";
}
This makes it easier to do things like:
someXMLParser.getValueByTagName(TagNames.RESOURCE_ID);
My question is this. If I want to iterate over all the fields declared in class TagNames, how do I do that? Pseudocode:
For tag in TagNames:
someXMLParser.getValueByTagName(tag)
I know I will probably have to restructure all of this. But I can't figure out a way to make the names easily accessible as well as iterable, without any duplication.
Any suggestions?
You're literally asking for a solution based on reflection, but I think a Java Enum may be a better choice in this case. Building on Frederick's example:
public class EnumTest {
public enum Tags {
RESOURCE_ID("ResourceId"),
REOURCE_NAME("ResourceName"),
RESOURCE_PRICE("ResourcePrice");
private final String tagName;
Tags(String tagName) {
this.tagName = tagName;
}
public String getTagName() {
return tagName;
}
}
public static void main(String[] args) {
for(Tags tag : Tags.values()) {
System.out.println("const:" + tag.name()
+ " tagName:" + tag.getTagName());
}
// API user might do e.g.:
// document.getValueForTag(Tags.REOURCE_NAME);
}
}
Although I agree that you should probably use enums or ResourceBundles, here's a solution to your actual question. A method that generates a Map name -> value from all public constants in a given class (the only thing that's missing should be try / catch or throws)
public static Map<String, Object> getConstantValues(Class<?> clazz){
Map<String, Object> constantValues = new LinkedHashMap<String, Object>();
for(Field field : clazz.getDeclaredFields()){
int modifiers = field.getModifiers();
if(Modifiers.isPublic(mod)
&& Modifiers.isStatic(mod) && Modifiers.isFinal(mod)){
constantValues.put(field.getName(), field.get(null));
}
}
return constantValues;
}
You may want to consider using a ResourceBundle instead of a class to store the tag names. May require a little bit of reworking of your code but it will be easier to produce a list of tags compared to what you are doing now, and adding a new tag won't require much work other then adding a line to the properties file.
You can do this quite easily using enum and an accompanying array:
public class Main {
public enum TagName { RESOURCE_ID, REOURCE_NAME, RESOURCE_PRICE }
private static String[] tags = {"ResourceID", "ResourceName", "ResourcePrice"};
public static String getValueByTagName(TagName tag) {
return tags[tag.ordinal()];
}
public static void main(String[] args) {
System.out.println("Calling by getValueByTagName:");
System.out.println(getValueByTagName(TagName.RESOURCE_ID));
System.out.println("Calling TagName.values() for loop:");
for (TagName t : TagName.values()) {
System.out.println(getValueByTagName(t));
}
}
}
Using an enum is a good fit, especially if you use a custom constructor and the built in "values" method:
public class Main {
public static enum TagName {
RESOURCE_ID("ResourceId"),
RESOURCE_NAME("ResourceName"),
RESOURCE_PRICE("ResourcePrice"),
;
private String s;
private TagName(String s) { this.s = s; }
public String toString() { return this.s; }
public static String[] strings() {
List<String> ss = new ArrayList<String>();
for (TagName tagName : TagName.values()) {
ss.add(tagName.toString());
}
return ss.toArray(new String[ss.size()]);
}
}
public static void main(String[] args) {
// Use TagName.values() for the enums, or for strings...
for (String s : TagName.strings()) {
System.out.println(s);
}
}
}
This way you can simply add new tags and they'll automatically get picked up by the "strings" method; for extra performance you could compute that string array just once, statically, since you can't change the set of enums dynamically. You could get even fancier by auto-generating the tag strings from their constant values, if they are really normalized...