How to cast String to the generic information that it represents? - java

My goal is to cast to a generic type, the information that a String contains, being this information variable between the different Java types. Ex:
String s = "10";
E e1 = (E)s;
String s = "abc";
E e2 = (E)s;
In this example e1 would be an Integer and e2 remains String. I have been searching for a solution during several hours, and the best I have found is a solution with reflection
However it cast to String, indepently if it contains other type of information, causing malfunctions in other parts of the code.

There's some terminological friction between your notion of "generic" (the kind of information that e.g. the 2nd and 3rd characters of "€10.-" might represent) and generic types, which is a Java technical term and concept.
There are some things below, that objects of class String are compatible with. Only Comparable is considered a generic type in the Java technical sense (here it has the type parameter <String>), all the rest is not.
public final class String implements java.io.Serializable,
Comparable<String>, CharSequence, Constable, ConstantDesc
You don't need to cast a String to any of them. You can just do stuff like this:
String s = "10";
CharSequence c = s;
If you go the other way round and you have CharSequence c then you can find out if it is actually String, and if it is, then you can cast. Btw. also the "reflection approach" you referred to tests (clazz.isAssignableFrom) before it casts.
CharSequence c = new StringBuffer("Käse");
if(c instanceOf String) // it is not, it is instanceOf StringBuffer
{
String anotherString = (String) c;
}
What you talked about isn't about casting but converting or evaluating. You can get an Integer from a String using Integer's conversion method valueOf().
Integer two = Integer.valueOf("2");
But it may fail, e.g. if you try this Integer.valueOf("€10.-") you'd get a NumberFormatException. You'd need to pick the numerical part only to make it work Integer.valueOf("€10.-".substring(1, 3))

Related

Why does this print exception?

String bob2 = "3";
System.out.println((int)bob2);
I'm unsure of why this causes an exception. Can anyone explain? Pretty sure because of the int on String type, but want to make sure.
Yes you are right its because of typecasting. If u need to convert String to int use below code
Integer.parseInt("3");
You are correct.
You can't just cast a string to an int.
You should convert it using Integer.parseInt()
Use this
Integer.valueOf("3");
or
Integer.parseInt("3");
In Java whenever you are trying to change type of an entity to another, both the types should have some relation. Like if you are trying to caste a sub class object to super class, it will work smoothly. But if you try to compare a Person object with a Lion object, that comparison is meaning less, the same is the logic in casting. We cannot cast a Person object to Lion object.
In your code bob is String type and you are trying to cast it to int and in Java both String and Integer is not having any relation. That's why Java is throwing Exception, Class Cast Exception I guess, this is raised when different types of objects are compared.
But the parseInt(String arg) method in Integer class gives an option to convert numeric String to Integer, given that the argument is a qualified Integer as per Java standards.
Example :-
String numericString = "1234";
int numberConverted = Integer.parseInt(numericString);
System.out.println(numberConverted);
You can also try these which will tell you the precautions before using this method
int numberConverted = Integer.parseInt("1234r");
int numberConverted = Integer.parseInt("1234.56");
int numberConverted = Integer.parseInt("11111111111111111111111111111");
You can't cast String to Integer. Change:
System.out.println((int)bob2);
to:
System.out.println(Integer.parseInt(bob2));
It will create an Integer value from the String provided with bob2 variable. You can also create a reference to int variable like this if you want to store primitive int instead of Integer:
int intBob2 = Integer.parseInt(bob2);

Java Cast from Object to long to String

Here's the situation, I have an Object in a Map which I explicitly know to contain an instance of Long and I need to turn that value into a string but keep getting incompatible type errors. Here's what my code looks like:
Map<String, Object> map = ...;
Object obj = new Long(31415L);
String str = Long.valueOf((long)map.get("id")); //Problem line
This gives:
Inconvertible types.
Found : java.lang.Object
Required: long
Any suggestions as to how to get around this?
You can just do
String str = map.get("id").toString();
Use, for instance:
String.valueOf(map.get("id"))
The problem is that you try and cast an object to a primitive type. That cannot work.
But since the values of your map will be Longs anyway (collections cannot contain primitive types, save for specialized implementations such as found in GNU Trove), look at #BheshGurung's answer...
You can use the toString function;
public String toString() {
return String.valueOf(map.get("id"))
}
String str = map.get("id").toString();
You have 2 issues here:
You created a *L*ong, not a *l*ong. Therefore you need to cast back to a *L*ong, not a *l*ong.
In order to get the String representation of a *L*ong you must call toString() on it.
Use this:
String str = ((Long)map.get("id")).toString();

Real world application of widening / narrowing conversion?

Can someone please explain why you would ever use widening or narrowing conversion? I've read a lot about these but no one ever gives me a practical example. Thanks!
(Java) Widening and Narrowing Conversions have to do with converting between related Types. Take, for example, the relationship between an abstract (super) class and its (child) subclass; let's use the java.lang.Number Class (abstract) and a direct subclass Integer. Here we have:
(superclass) Number
__________/\__________
/ | | \
(concrete subclasses) Integer Long Float Double
Widening Conversion: occurs if we take a specific type (subclass) and attempt to assign it to a less specific type (superclass).
Integer i = new Integer(8);
Number n = i; // this is widening conversion; no need to cast
Narrowing Conversion: occurs when we take a less specific type (superclass) and attempt to assign it to a more specific type (subclass), which requires explicit casting.
Number n = new Integer(5); // again, widening conversion
Integer i = (Integer) n; // narrowing; here we explicitly cast down to the type we want - in this case an Integer
There are certain issues that you need to be aware of such as ClassCastExceptions:
Integer i = new Integer(5);
Double d = new Double(13.3);
Number n;
n = i; // widening conversion - OK
n = d; // also widening conversion - OK
i = (Integer) d; // cannot cast from Double to Integer - ERROR
// remember, current n = d (a Double type value)
i = (Integer) n; // narrowing conversion; appears OK, but will throw ClassCastException at runtime - ERROR
One way to handle this is to use an if statement with the instanceof keyword:
if( n instanceof Integer) {
i = (Integer) n;
}
Why would you want to use this? Let's say you are making a hierarchy of personnel for some program and you have a generic superclass called "Person" which takes a first and last name as parameters, and subclasses "Student", "Teacher", "Secretary", etc.. Here you can initially create a generic person, and assign it (through inheritance) to, say, a Student which would have an additional variable field for studenID set in it's constructor. You can use a single method that takes the more generic (wider) type as a parameter and handle all subclasses of that type as well:
public static void main(String[] args) {
Person p = new Student("John", "Smith", 12345);
printInfo(p);
}
// this method takes the wider Person type as a parameter, though we can send it a narrower type such as Student if we want
public static void printInfo(Person p) {
System.out.println("First: " + p.getFirstName());
System.out.println("Last: " + p.getLastName());
if (p instanceof Student) {
System.out.println( (Student)p).getStudentID() ); // we cast p to Student with Narrow Conversion which allows us to call the getStudentID() method; only after ensuring the p is an instance of Student
}
}
I realize this may not be the ideal way to handle things, but for the sake of demonstration I thought it served to show some of the possibilities.
If some code returns an int containing a true/false value, you could shorten it yourself to a bool which is what it properly represents.
You can also do the opposite.
You can widen a char to int to do some comparisons with ascii values.
You can take an instance of Dog and widen it to IAnimal to pass it to a function.
You can shorten a IAnimal to Dog when you know the type of animal in a List<IAnimal> in a factory or elsewhere for whatever reason.
You use implicit conversions to do math with numerical values of different types. For example, if now() returns a timestamp in seconds as a long:
long t = now()
long nextMinute = t + 60
you have done an implicit widening conversion of 60 (an int) to a long so you can add it to t. Being able to do such conversions makes math much easier to code.
One canonical example of widening and narrowing conversions is how certain file I/O libraries work. Often, a file processing library will have a function / method that reads a single character from a file. If there is a character to read, the function should return that character, and if no characters are left it should return a sentinel value EOF to signal this.
Because any character can appear in a file, typically the function / method would have this signature:
int readCharacter();
Here, the function returns an int that holds a char value if a character was read and which holds EOF as a sentinel otherwise. EOF is typically chosen as an integer that is too big to hold in a char. That way, you can do this:
while (true) {
int ch = readCharacter();
if (ch == EOF) break;
char actualCharValue = (char) ch;
/* process actualCharValue here */
}
Hope this helps!
Take this...
Conversion - Specialized -> Generalized, then it is known as Widening, when you are becoming more general.
Such as Surgeon -> Medico. In this case, you do not need a casting. Because, a surgeon is a Medico by default. So, it is natural that a surgeon can perform all those stuffs that a Medico can do.
While on the other hand,
Conversion - Generalized -> Specialized, then it is known as narrowing, when you are becoming more specialized.
Such as Medico -> Surgeon. Well, in this case, you must have to add casting. Because, a medico can be a surgeon or a physician or a nurse. Think of it, if you ask a nurse to operate on you...
Horrible, right ???
Hope you got the idea.

Why cannot cast Integer to String in java?

I found some strange exception:
java.lang.ClassCastException: java.lang.Integer
cannot be cast to java.lang.String
How it can be possible? Each object can be casted to String, doesn't it?
The code is:
String myString = (String) myIntegerObject;
Thanks.
Why this is not possible:
Because String and Integer are not in the same Object hierarchy.
Object
/ \
/ \
String Integer
The casting which you are trying, works only if they are in the same hierarchy, e.g.
Object
/
/
A
/
/
B
In this case, (A) objB or (Object) objB or (Object) objA will work.
Hence as others have mentioned already, to convert an integer to string use:
String.valueOf(integer), or Integer.toString(integer) for primitive,
or
Integer.toString() for the object.
No, Integer and String are different types. To convert an integer to string use: String.valueOf(integer), or Integer.toString(integer) for primitive, or Integer.toString() for the object.
For int types use:
int myInteger = 1;
String myString = Integer.toString(myInteger);
For Integer types use:
Integer myIntegerObject = new Integer(1);
String myString = myIntegerObject.toString();
No. Every object can be casted to an java.lang.Object, not a String. If you want a string representation of whatever object, you have to invoke the toString() method; this is not the same as casting the object to a String.
You can't cast explicitly anything to a String that isn't a String. You should use either:
"" + myInt;
or:
Integer.toString(myInt);
or:
String.valueOf(myInt);
I prefer the second form, but I think it's personal choice.
Edit OK, here's why I prefer the second form. The first form, when compiled, could instantiate a StringBuffer (in Java 1.4) or a StringBuilder in 1.5; one more thing to be garbage collected. The compiler doesn't optimise this as far as I could tell. The second form also has an analogue, Integer.toString(myInt, radix) that lets you specify whether you want hex, octal, etc. If you want to be consistent in your code (purely aesthetically, I guess) the second form can be used in more places.
Edit 2 I assumed you meant that your integer was an int and not an Integer. If it's already an Integer, just use toString() on it and be done.
Objects can be converted to a string using the toString() method:
String myString = myIntegerObject.toString();
There is no such rule about casting. For casting to work, the object must actually be of the type you're casting to.
You should call myIntegerObject.toString() if you want the string representation.
Casting is different than converting in Java, to use informal terminology.
Casting an object means that object already is what you're casting it to, and you're just telling the compiler about it. For instance, if I have a Foo reference that I know is a FooSubclass instance, then (FooSubclass)Foo tells the compiler, "don't change the instance, just know that it's actually a FooSubclass.
On the other hand, an Integer is not a String, although (as you point out) there are methods for getting a String that represents an Integer. Since no no instance of Integer can ever be a String, you can't cast Integer to String.
In your case don't need casting, you need call toString().
Integer i = 33;
String s = i.toString();
//or
s = String.valueOf(i);
//or
s = "" + i;
Casting. How does it work?
Given:
class A {}
class B extends A {}
(A)
|(B)
B b = new B(); //no cast
A a = b; //upcast with no explicit cast
a = (A)b; //upcast with an explicit cast
b = (B)a; //downcast
A and B in the same inheritance tree and we can this:
a = new A();
b = (B)a; // again downcast. Compiles but fails later, at runtime: java.lang.ClassCastException
The compiler must allow things that might possibly work at runtime. However, if the compiler knows with 100% that the cast couldn't possibly work, compilation will fail.
Given:
class A {}
class B1 extends A {}
class B2 extends A {}
(A)
/ \(B1) (B2)
B1 b1 = new B1();
B2 b2 = (B2)b1; // B1 can't ever be a B2
Error: Inconvertible types B1 and B2.
The compiler knows with 100% that the cast couldn't possibly work. But you can cheat the compiler:
B2 b2 = (B2)(A)b1;
but anyway at runtime:
Exception in thread "main" java.lang.ClassCastException: B1 cannot be cast to B2
in your case:
(Object) / \(Integer) (String)
Integer i = 33;
//String s = (String)i; - compiler error
String s = (String)(Object)i;
at runtime: Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
Use String.valueOf(integer).
It returns a string representation of integer.
Use .toString instead like below:
String myString = myIntegerObject.toString();

Indicate datatype from a input string?

For example i have a string input "int",can i declare a variable base on that input?
(Not switch check please). I mean something like this (pseudo-code) or similar:
String str="int";
new (variable_name,"int");
// create new variable with int datatype.
You can do this:
String className = "MyClass";
Object obj = Class.forName(className).newInstance();
But it won't work for primitive types.
If instead of using primitive types you will use cannonical name of Object based class you can try to do this
public Object loadClass(String className) {
return Class.forName(className).newInstance(); //this throw some exceptions.
}
Not practically, Java is strongly typed and the type of all variables must be known at compile time if you are to do anything useful with them.
For example, you could do something like this;
String str = "java.lang.Integer";
Class clazz = Class.forName(str);
Object o = clazz.newInstance();
..which will give you an Object o whose type is determined at runtime by the value of the String str. You can't do anything useful with it though without first casting it to the actual type, which must be known at compile time.

Categories