Please explain how type conversion in Java (Double / double, Integer / integer, ...) works.
Why is only the last example valid?
setLocation(double, double);
// This don't work
player.setLocation((Double) jsonMsg.get("x"), (Double) jsonMsg.get("y"));
// This don't work too
player.setLocation((double) jsonMsg.get("x"), (double) jsonMsg.get("y"));
// It's ok!
player.setLocation( Double.parseDouble(jsonMsg.get("x").toString())
, Double.parseDouble(jsonMsg.get("y").toString())
);
Seems that your jsonMsg.get("x") returns an object which string representation can be converted to a double type value.
And your setLocation method needs two double type parameters, i.e declared as
setLocation(double a, double b)
To convert strings to double you need to invoke Double.parseDouble(). It parses parameter string to a double value and returns it.
UPDATE:
in java it is not possible to cast an object variable to a primitive type. So you need to invoke a parsing method of a Double class to convert this string object to a double type value.
Java do type conversion implicitly between Wrapper class(Integer,...) and Primitive type (int,...) after Java 1.5.
but what you're trying to do in the first two steps is to cast Object/String into Double which is not allowed and need explicit manipulation like Double.parseDouble(jsonMsg.get("x").toString()) or new Double("1.2").
Thanks
Notice: String is a object and if you want to convert object type to primitive type you have to use wrapper/covering classes. You cannot do casting.
Java has wrapper classes for every primitive data types. As a example:
int - Integer
double - Double
Wrapper classes have methods to manipulate primitive data types and to convert objects to primitive data types. As a example:
For int - Integer.parseInt()
For double - Double.parseDouble()
In your code snippet last line:
Double.parseDouble(jsonMsg.get("x").toString()
you are parsing String to double it is correct and in other two line you are trying to cast. In one using wrapper class:
player.setLocation((Double) jsonMsg.get("x"), (Double) jsonMsg.get("y"));
and other one using primitve type:
player.setLocation((double) jsonMsg.get("x"), (double) jsonMsg.get("y"));
Both are incorrect. Because of jsonMsg.get("x") returns String object. You have to convert it into String using .toString() and parse it to double.
Notice: toString() method is used when we need a string representation of an object.
I hope you get the point.
Related
In the book "SamsTeachYourself Java" there is a task that goes like this:
"Write a Java application that takes an argument as a string, converts it to a float variable, converts that to a Float object, and finally turns that into an int variable. Run it a few times with different arguments to see how the results change."
Could someone clarify this text, especially the first part about a java application that takes an argument as a string?
In Java programs start with
public static void main(String[] args){
args is a variable of type String[] (an array of Strings). You can call call functions like args.length() which will return the number of arguments made to the program.
This array is populated with the things that follow the name of the program when you call it. For example if you called your program like:
java MyProgram ate my dog
The variable args would have length three and contain the values "ate", "my", "dog". The following lines would all return true.
args[0].equals("ate");
args[1].equals("my");
args[2].equals("dog");
These other answers will also help explain this
What is "String args[]"? parameter in main method Java
args.length and command line arguments
In IDE like Eclipse you don't type the command that executes these lines but you can configure your project to run with a predetermined set of values. For how to do this in eclipse see this other answer: Eclipse command line arguments
Following the input of a String that represents a float (ex. "1.98") Java contains a number of useful functions for parsing strings into other types. Many of these are contained in classes which wrap the primitive types. One of these is the object type Integer which contains a function called parseInt which takes a String as an argument and returns an int. Similar classes exist for other primitive types as well, including doubles and floats.
Variables of these types can be constructed from their corresponding primitive types. Here is the online documentation of these constructors for the Integer class.
Finally the problem asks you to convert a float to an int. In java you can call a type cast operation like so:
float a = 8.88;
int b = a; //error, loss of precision
int c = (int)a;
When typecasting a float or a double to an int the value is not rounded, it is truncated. In my example above the variable c has a value of 8, not 9.
In terms of instances of wrapper classes, does the instance behave differently when the instance is created via a String arg in the constructor in comparison to an int, double etc.
E.g is there a difference in:
Integer wrapperInt= new Integer(33);
Integer wrapperInt2= new Integer("33");
The end result will be the same - you'll have an Integer object with the value 33.
The version that takes a String will throw a NumberFormatException if the input string cannot be parsed.
Note: There's no need to write a statement like Integer wrapperInt = new Integer(33);. Let the compiler do it for you (auto-boxing):
Integer wrapperInt = 33;
If, for some reason, you do not want to use auto-boxing, then at least use Integer.valueOf(...) instead of using the constructor:
Integer wrapperInt = Integer.valueOf(33);
This is more efficient; the valueOf method can return a cached object (so that it's not necessary to create a new Integer object).
No, it doesn't. Both instances represent the integer 33. If there was a difference, it would be written in the javadoc.
Note that you should favor the usage of the factory methods instead:
Integer i = Integer.valueOf(33);
i = Integer.valueOf("33");
The only difference is you will be creating a string object unnecessarily in the second approach and it will try to parse the string you have passed to the constructor, If it couldn't parse the string then it will throw NumberFormatException.
The answer is that yes, there can be a difference between the two syntaxes. Specifically, the syntax
new Integer(33);
results in the value 33 being interpreted as an integer constant by the compiler and stored as a literal in the code. By contrast, the syntax
new Integer("33");
results in a call that routes the string value through Integer.parseInt(s, 10). This matters if the value in question has a leading zero character; in the case of an int literal, the compiler will evaluate the literal as octal:
new Integer(010); // equals 8
By contrast, the string constructor will always evaluate the value as base 10:
new Integer("010"); // equals 10
In any case, you should almost always be using Integer.valueOf(), as it is usually more efficient.
How to get an Integer instead of Long from JSON?
I want to read JSON in my Java program, but when I get a JSON value which is a number, my parser returns a number of type Long.
I want to get an Integer. I tried to cast the long to an integer, but java throws a ClassCastException (java.lang.Long cannot be cast to java.lang.Integer).
I tried several things, such as first converting the long to a string, and then converting with Integer.parseInt(); but also that doesn't work.
I am using json-simple
Edit:
I still can't get it working. Here is an example:
jsonItem.get("amount"); // returns an Object
I can do this:
(long)jsonItem.get("amount");
But not this:
(int)jsonItem.get("amount");
I also can't convert it with
Integer newInt = new Integer(jsonItem.get("amount"));
or
Integer newInt = new Integer((long)jsonItem.get("amount"));
Please understand that Long and Integer are object classes, while long and int are primitive data types. You can freely cast between the latter (with possible loss of high-order bits), but you must do an actual conversion between the former.
Integer newInt = new Integer(oldLong.intValue());
I tried
(int)(long)jsonItem.get("amount");
and it worked for me
What is the best way to assign a value with type conversion to a property of an object in Java.
For eg: A Person class with age field as an integer. If the following statement has to assign integer 21 to age field, then what should be the implementation of set method? [Note: 21 is passed as string]
ObjectUtils.set(person, "age", "21");
One way is to get the type of the field and type cast explicitly. Is there any better approach or library utility available to achieve this?
Take a look at BeanUtils.setProperty():
Set the specified property value, performing type conversions as required to conform to the type of the destination property.
You can achieve this by using reflexion:
using this you can get the attribute type dynamically, something like this:
Person p = ...; // The object you want to inspect
Class<?> c = p.getClass();
Field f = c.getDeclaredField("age");
f.setAccessible(true);
String typeOfAge = (String) f.getType(p);
After you have the attribute type its easy to cast the value.
use Integer.parseInt(String) in your set method. Make sure you catch the exception for an invalid number. Here is hte javadoc for parseInt
parseInt
public static int parseInt(String s) throws NumberFormatException Parses the string
argument as a signed decimal integer. The characters in the string
must all be decimal digits, except that the first character may be an
ASCII minus sign '-' ('\u002D') to indicate a negative value. The
resulting integer value is returned, exactly as if the argument and
the radix 10 were given as arguments to the parseInt(java.lang.String,
int) method. Parameters: s - a String containing the int
representation to be parsed Returns: the integer value represented by
the argument in decimal. Throws: NumberFormatException - if the string
does not contain a parsable integer.
I am not experienced in Java at all and am using a text editor to write code so I can't see what the problem is (I am running from command line)
I see the error and know what it is but I have no idea how to fix it
System.out.print(String.format("%7d", Math.pow(n,2).toString()));
I also tried without the .toString()
Basically if I print only n it works, but the power function gives me an error probably because of return types, but pow should return a double and the string format %7d is probably also double right?
You are using wrong format specifier.. %d is used for integer.
Math.pow() returns primitive double on which you cannot invoke toString() method.
Try using %7s which is for String, and convert your primitive double value to Wrapper type: -
String.format("%7s", Double.valueOf(Math.pow(n,2)).toString())
But, you don't need to convert your argument to String, you can directly use double value with %f: -
String.format("%.3f", Math.pow(n,2));
You most likely want to use f instead of d without the toString. If you actually were able to do toString (as Quoi points out, you cannot do from a primitive), it would make it impossible to use Formatters that expect the used Number object (Double in your case).
This is the Formatter that String.format uses.
problem lies with toString method. You have given format specifier %7d that means integer. You can't print string in place of it.
The Right Format for double is %f not %d so modify your code to:
System.out.print(String.format("%7f", Math.pow(n,2)));
see also :link
Math#pow(double,double) returns primitive double value you can not call toString method.
Use f instead of d, and d is for a decimal integer.
System.out.format("%7f", Math.pow(n,2));
Better start with Eclipse or any other editor to write code.