I have been trying to convert an object to a string and then have that string value assigned to a string I have already defined.
Currently I have this
public static final String stringthing;
^ so at the beginning of the code I have pretty much said I have a string but I haven't assigned a value to it.
When I try to convert an object to string and then set that string equal to my unassigned string value "stringthing" I keep getting "unexpected type, found value require variable". The thing I don't understand is why can't I assign that string value to stringthing?
for (Object student : students) {
System.out.println(student.toString())=stringthing;
}
I have seen other topics regarding "unexpected type, found value require variable" in which I only saw things orienting around integers, however I don't understand why this isn't legal or okay in Java? Is there something syntax-wise that I don't understand?
System.out.println(...);
Does print a string to stdout
if you want to assign student.toString() to stringthing, then do :
stringthing = student.toString();
And after you can do :
System.out.println(stringthing);
public class Foo {
public static String stringthing;
public static List<Object> students;
// [...]
public static void bar() {
for (Object student : students) {
stringthing = student.toString();
System.out.println(stringthing);
}
}
}
Is this what you are trying to do?
First you cannot reset the value of a final variable, so it has to be "non-final". Second the assignment was wrong.
System.out.println(student.toString())
That is a method call that prints what ever student.toString() returns. You can't assign a value to that method call. That is simply not possible.
You have a big mix up there. What ever you try, you are doing it wrong in every possible way.
Related
I've got a method that creates a String and another method that changes Strings
void create(){
String s;
edit(s);
System.out.println(s);
}
void edit(String str){
str = "hallo";
}
My compiler says that it "may not have been initialized".
Can someone explain this?
Variable may not have been initialized
As you define the s inside a method you have to init s in it somewhere every variable in a program must have a value before its value is used.
Another thing not less important, your code won't never work as you expected cause
Strings in java are inmutable then you cannot edit your String, so you should change your method edit(Str s).
I Change your code to something like this but i think your edit method should do another thing rather than return "hallo".
void create(){
String s=null;
s =edit(); // passing a string to edit now have no sense
System.out.println(s);
}
// calling edit to this method have no sense anymore
String edit(){
return "hallo";
}
Read more about that java is passed by value in this famous question : Is Java "pass-by-reference"?
See this simple Example showing that java is passed by value. I cannot make an example with only Strings cause Strings are inmutable. So i create a wrapper class containing a String that is mutable to see differences.
public class Test{
static class A{
String s = "hello";
#Override
public String toString(){
return s;
}
}
public static void referenceChange(A a){
a = new A(); // here a is pointing to a new object just like your example
a.s = "bye-bye";
}
public static void modifyValue(A a){
a.s ="bye-bye";// here you are modifying your object cuase this object is modificable not like Strings that you can't modify any property
}
public static void main(String args[]){
A a = new A();
referenceChange(a);
System.out.println(a);//prints hello, so here you realize that a doesn't change cause pass by value!!
modifyValue(a);
System.out.println(a); // prints bye-bye
}
}
You declare local variable s in method create, so that you need to initialized it before you use it. Remember that java does not have default value for local variable.
Init String s = "" or whatever value than your code will run normally.
try to initialize the string "s" to a null value, since you have declared a variable "s" but it has not been initialized. Hence it can't pass the reference of that variable while used as parameter.
String s = null;
Hope this helps
Give your variable S a value or as Jeroen Vanneve said "Change it to String s = null;"
public class Tester {
private String text;
public void text() {
text = "abc";
}
public static void main(String[] args) {
Tester test = new Tester();
System.out.println(test.text);
}
}
Why does this print null? Also, if I write test.text() inside the print command, why there is an error? I thought I needed to invoke the method like that.
null because private String text; is null as you have not made call to your public void text() which sets the value of String text
Make call to your text() before printing
Tester test=new Tester();
test.text();
System.out.println(test.text);
Output:
abc
PS.
As per comment => "Can I directly write System.out.println(test.text())? "
For that set return type to String and return String from it
So Change your code to
public String text() {
return "abc";
}
And
Test test = new Test();
System.out.println(test.text());
Output:
abc
It is printing null because the default value of all Class types is null, you have not set text and still trying to print.
if you want to print abc then follow either of the following ways
1 call you text method explicitly like test.text();
2 initialize yourtext in constructor as follows
Tester(){
text="abc";
}
Your String object is assigned null at construction time - that is, when you declare new Tester(), your text field is assigned null. This is the default value of all object types, and all primitives are assigned zero (or false, if the primitive is a boolean).
Nothing's assigned to it, and the default behavior of printing out null is to print the literal text "null".
As for your second question - the reason that this won't work:
System.out.println(test.text());
text() is a method call that returns void, or nothing. There's nothing that is returned as a result of the method call, so nothing can be printed out.
You would want to move your call to text() before any print statements, so the field is properly populated:
Tester test = new Tester();
test.text();
System.out.println(test.text);
...and, there is a convention for something like this: if you want the field to be populated at construction time, create a constructor that accepts it as an argument.
public Tester(String text) {
this.text = text;
}
When you construct it, you don't need to worry about any extraneous call to text(); just print the field.
Tester test = new Tester("abc");
System.out.println(test.text);
You should call test.text(); firstly to give test a value.
As text is a class variable so it is by default initialized to null.If it would be int then it would have been initialized to 0;
In your program you are not calling text() so the value of text is not changed.Now in the main method you are printing text so its printing null;
Also, if I write test.text() inside the print command, why there is an error?
this is because the return type of text() is void
Here's a question that goes right back to basics (I think) although had me stumped in a recent coding project I undertook with a few friends.
Here's code variation one:
public class Test {
private String test;
public Test(){
test = "tester";
changeString(test);
}
public void changeString(String t){
t = "blue apples";
}
public String getTest(){
return test;
}
public static void main(String[] args){
Test t = new Test();
System.out.println(t.getTest());
}
}
Why does the program print out "tester" instead of "blue apples"? Shouldn't the method changeString(String) turn the field 'test' into "blue apples"?
Thanks for your responses in advance!
Java is pass by value and not pass by reference. Therefore, the changes made to the passed t String, won't be reflected in your test String.
public void changeString(String t){
t = "blue apples";
test = t; // Include this line to assign the value of `t` to `test`.
}
First you assign "Tester" to test. Next you call changeString passing it a reference of test.
This method simply assigns "blue apples" to t. In doing so, it creates a new String before making the assignment. Because t is passed by value, the change is not reflected when the method returns
Instead, you would need to do something more like...
public void changeString(String t){
text = t;
}
And use changeString("blue apples");
or
public String changeString(){
return "blue apples";
}
And use test = changeString();
You are doing,
test = "tester";
changeString(test);
String is immutable in java.
public void changeString(String t){
t = "blue apples";
}
In the above lines you are changing the value of the parameter passed to that method, Not the test.
To see change try
public void changeString(String t){
t= "blue apples";
test=t; // now assigned the value
}
String is immutable in JAVA. Immutablity means once an instance is created it remains the same. In your case
In your case you created a tester reference to point to a new String "Tester"
Since string is immutable when you passed the object to the method and tried to reassign the reference to a new String "Blue Apples" what you did was created a reference t in the scope of method which pointed to blue apples. If you would had had printed t you would have got "Blue Apples" since the scope of t is till the method.
After returning the tester reference still points to the same old string "tester" and hence it gets printed.
As with String all other wrapper classes are also immutable. You would observe same behavior with Integer, Boolean objects
This happens because String object is immutable, hence cannot change its value post assignment. You can use StringBuffer or StringBuilder isntead
I know that in Java, everything is passed by value. But for objects, it is the value of the reference to the object that is passed. This means that sometimes an object can get changed through a parameter, which is why, I guess, people say, Never modify parameters.
But in the following code, something different happens. s in changeIt() doesn't change when you get back to main():
public class TestClass {
static String str = "Hello World";
public static void changeIt( String s ) {
s = "Good bye world";
}
public static void main( String[] args ) {
changeIt( str );
System.out.println( str );
}
}
I'm guessing -- and I'd like confirmation -- that when you say s = "something" it's the same or equivalent to saying String s = new String("something"). Is this why s doesn't change? Is it assigned a whole new object locally which gets thrown away once you exit changeIt()?
that when you say s = "something" it's the same or equivalent to saying String s = new String("something")
Yes, pretty much. (though the JVM might do optimizations so that the same string literal used several times refers to the same String object).
Is this why s doesn't change? Is it assigned a whole new object locally which gets thrown away once you exit changeIt()
Yes. As you say, everything is passed by value in Java, even references to object. So the variable s in changeIt( String s ) is a different value from str you use in main(), it's just a local variable within the changeIt method.
Setting that reference to reference another object does not affect the caller of changeIt.
Note that the String object s refer to is still the same String as str refers to when entering the changeIt() method before you assign a different object to s
There's another thing you need to be aware of, and that is that Strings are immutable. That means that no method you invoke on a string object will change that string. e.g. calling s.toLowerCase() within your changeIt() method will not affect the caller either. That's because the String.toLowerCase() does not alter the object, but rather returns a new String object.
When you write
s = "Good bye world";
you are changing the value of s to be a reference to the new string. You are not changing the value of the string referenced by s.
Yes, now 'S' points to brand new object whose scope is limited to that method. String may not be perfect example to understand pass-by-value concept. Instead of string, let us say pass some mutable object reference and make changes to that assign new object inside the method. You don't see them outside of the object.
public class MyMain {
private static void testMyMethod(MyMain mtest) {
mtest=new MyMain();
mtest.x=50;
System.out.println("Intest method"+mtest.x);
}
int x=10;
public static void main(String... args)
{
MyMain mtest = new MyMain();
testMyMethod(mtest);
System.out.println("In main method: "+mtest.x);
}
}
Read second answers in this SO discussion.
I have created a no. of constant variables, more than 1000, those constants are unique integer.
public static final FOO 335343
public static final BAR 234234
public static final BEZ 122424
....
....
....
Is there a way to print out the FOO, BAR and BEZ, the variable of the names in Java?
I am not familiar with java reflection. I don't know if that helps.
if ( FOO == 335343)
---> output "FOO"
if ( BAR == 234234 )
---> ouptut "BAR"
....
Actually asking this question behind is that I want to write log into the file
say
System.out.println("This time the output is " + FOO);
and the actual output is
This time the output is 335323
I want to know which variable comes from 335323.
Is there any other way apart from putting those variable and its associate constant into hashMap?
Thanks
There are some 'special case' that u can have workaround for this (which is told by other), but the most important question is: why would you want to do this (printing out variable name)?
From my experience, 99.9% of similar questions (how to print variable name? how to get variable depends on user inputting variable name? etc) is in fact raised by beginner of programming and they simply have made incorrect assumptions and designs. The goal they are trying to achieve normally can be done by more appropriate design.
Edit
Honestly I still do not think what you are trying to do is the way to go, but at least I think the following is a workable answer:
It is more or less a combination of previous answer:
(Haven't try to compile but at least it give u an idea)
class Constants {
public static final int FOO = 123;
public static final int BAR = 456;
private static Map<Integer, String> constantNames = null;
public static String getConstantName(int constVal) {
if (constantNames == null) {
Map<Integer, String> cNames = new HashMap<Integer, String>()
for (Field field : MyClass.class.getDeclaredFields()){
if ((field.getModifiers() & (Modifier.FINAL | Modifier.STATIC)) != 0) {
&& int.class == field.getType()){
// only record final static int fields
cNames.put((Integer)field.get(null), field.getName());
}
}
constNames = cNames;
}
return constantNames.get(constVal);
}
}
assuming you want to get a constant name, just do:
Constants.getConstantName(123); // return "FOO"
As I noted in my comment to the original post, I have a strong suspicion that the best solution for your current problem is to solve it in a completely different way. You seem to want to associate an int with a String, and one way to do this is to use a Map such as a HashMap. For e.g.,
import java.util.HashMap;
import java.util.Map;
public class MapDemo {
public static void main(String[] args) {
Map<Integer, String> myMap = new HashMap<Integer, String>();
myMap.put(335343, "FOO");
myMap.put(234234, "BAR");
myMap.put(122424, "BEZ");
int[] tests = {335343, 234234, 122424, 101010};
for (int i : tests) {
// note that null is returned if the key isn't in the map
System.out.printf("%d corresponds to %s%n", i, myMap.get(i));
}
}
}
Edit 1:
Per your recent comments and update to your original question, I take it that you have many numbers and their associated Strings involved in this program and that your need is to find the String associated with the number. If so, then you need to think re-design, that the numbers and their strings should not be hard-coded into your program but rather be part of the program's data, perhaps in a text file with one column being the numbers and the next column (separated by a space perhaps), the associated text. This way you could read in the data and use it easily in a HashMap, or data base, or really any way that you desire. This will give your project much greater flexibility and robustness.
You can use something like:
for (Field field : MyClass.class.getDeclaredFields()){
if (field.getType().toString().equals("int")){
int val = (Integer)field.get(MyClass.this);
switch (val){
case 335343:
case 234234:
System.out.println(field.getName());
}
}
}
Remember to change MyClass for your class name and that at least one instance should exist to get the value of the field. So, if you are planning on testing the code in a main method, you should change MyClass.this to something like new Myclass().
Another thing to remember is that the fields are attributes and not method variables (so it won't work if you are using this to access variables declared inside a method).
You can use enum.
If these numbers just need to be unique, you can say
public enum Yourname {
FOO, BAR, BEZ
}
and refer to the name as Yourname.FOO and the value as Yourname.FOO.ordinal(). You can use enums for if-blocks, switch-statements.
If you want to have the numbers you gave in the question, so if FOO needs to be 335343, you can create numbered enums. Have a look at is-it-possible-to-assign-numeric-value-to-an-enum-in-java and number-for-each-enum-item.
I would suggest that you print out the line number, not the variable name. That should give you enough to determine where the message is coming from. Here's more info on how to do that:
How can we print line numbers to the log in java
I had a similar problem with a long list of int variables that I had to print the name of each variable and its value (main goal was to create a text file that was going to be imported in an Excel file).
Unfortunately I'm quite new in Java programming, so the only solution that I found (probably wrong) is to use two different arrays: one String array for the String name and another Int array for the corresponding values.
For example:
int varName01, varName02, ....
String[] listNames = new String {"varName01", "varName02", .....
int[] listValues = new int {varName01, varName02, .....
for (int i=0; i<listValues.length;i++)
{
print String.format("%s %d", listNames[i], listValues[i]);
}
Probably this is not the correct way to do it, so any opinion from some Java expert would be more than welcome. Thanks!