Why class cast exception from Double to double?
Used like:
Console.writeLine(Validator.TryParse("1.5", double.class));
Code:
public static <T> T TryParse(Object ConvertFrom, java.lang.Class<T> ConvertTo) {
switch(ConvertTo.getSimpleName().toLowerCase()) {
case "int":
case "integer": return ConvertTo.cast((int)Integer.parseInt((String)ConvertFrom));
case "string": return ConvertTo.cast(String.valueOf(ConvertFrom));
case "double": return ConvertTo.cast((double)Double.parseDouble((String)ConvertFrom));
case "float": return ConvertTo.cast((float)Float.parseFloat((String)ConvertFrom));
case "long": return ConvertTo.cast((long)Long.parseLong((String)ConvertFrom));
default: return null;
}
}
You are mixing primitives and boxed primitives. Calling TryParse("1.5", Double.class) will work fine (and you can remove all the unnecessary primitive casts like (int) (double) etc).
The problem you encounter is that Class#cast first checks Class#isInstance and:
Double.class.isInstance(1.0);
is true but:
double.class.isInstance(Double.valueOf(1.0))
double.class.isInstance(1.0d)
are false as explained in the javadoc
If this Class object represents a primitive type, this method returns false.
Bottom line: primitive.class.cast() will always throw an exception.
If you still need to define the class each time you call the validator, why don't you just use the valueOf method of each class? The Object classes such as Integer and Double will be able to handle the primitives and return objects...
As it's been asked before, are you sure you need to implement this? You might want to review your design.
It should be as below, Note the Caps in Double.
Console.writeLine(Validator.TryParse("1.5", Double.class));
You can use Double.doubleValue() and Integer.intValue().
More reading:
Double.doubleValue()
Integer.intValue()
Except....
Your method wants to return an Object, so you can't return primitives.
Editorial:
It seems like you're trying to do something that is very unnatural and un-Java (Java is a typed language for a reason).
Related
I have a string that tells me what I want to cast my object to, Is there a way to cast to that object?
Here is some pseudo code that defines what I would like to do
public TypeToCastTo Cast(T object, String TypeToCastTo) {
switch (TypeToCastTo) {
case "foo":
return (foo)T;
case "otherType":
return (otherType)T;
...
}
}
edit
I wanted to create a game where I can click on a button to purchase something e.g. sword or armour which inherits from worldObject. I figure since I might be returning a weapon or armour class (which both inherit from worldObject) that it would make sense to return a worldObject and then downcast to the correct class (Based off it's name (String)).
edit 2:
As mentioned in the comments this is an XY problem. I was originally trying to make a function that would return the downcast type but in reality that doesn't make sense, since in the case it is used somewhere else, i will need a switch statement to determine what to do with the object anyway (at this point i can cast) so rather than having
public TypeToCastTo Cast(T object, String TypeToCastTo) {
switch (TypeToCastTo) {
case "foo":
return (foo)T;
...
}
}
And using my function to cast the WorldObject, I can have
Method DoingSomethingWithWorldObject(WorldObject T) {
switch(T.typeToCastTo) {
case "foo":
foo temp = (foo)T;
// code using temp
case "other":
other temp = (other)T;
// code using temp
...
}
}
although several people mentioned it was probably wrong the way i was thinking of doing it, Including the answer i have marked correct (Which answered my question even though i was asking the wrong question), The reason i actually understood this was because of a response that was deleted.
As mentioned in the comments, you can do this by using reflection with the Class.cast method:
public Object cast(Object object, String typeToCastTo) {
switch (typeToCastTo) {
case "foo":
return Foo.class.cast(object);
case "otherType":
return OtherType.class.cast(object);
}
}
However the return type of the method needs to be Object as you don't know the actual return type that is encoded in the typeToCastTo parameter.
That is it only makes at least some sense, if you have an instance of Class at hand:
Class<Foo> fooClass = (Class<Foo>) Thread.currentThread().getContextClassLoader().loadClass("my.foo.Foo");
Foo fooObject = foo.cast(object);
But all of this seems rather pointless...
Based on the comments. To invoke a parent class' private method, you don't need to cast:
Object object = new SubFoo();
Method privateFooMethod = Arrays.asList(ParentFoo.class.getDeclaredMethods())
.stream().filter(m -> m.getName().equals("privateFooMethod")).findAny()
.get();
privateFooMethod.setAccessible(true);
privateFooMethod.invoke(object);
But you should really think twice before using reflection to achieve something like this. This very much looks like a bad class/interface design resulting in weird solutions for rather basic needs.
Alternative approach (though I don't know if it's considered bad practice):
public TypeToCastTo Cast(T object, String TypeToCastTo) {
switch (TypeToCastTo) {
case "foo":
return new Foo(object);
case "otherType":
return new OtherType(object);
...
}
}
You'll need specific constructors with corresponding parameters (overloaded) for the different types you'd like to address though. Within those constructors you can control the exact "translations" from one type to another.
I would like a method to read a string, and return it's value in the implied (best fitting) data type. I would like to avoid doing the string to data type conversion in "main", as the code is likely to create clutter. Is this possible? Can I create a method that returns different types? What does the constructor look like?
It's not possible to return different primitive types. What you can do is declare the method as returning Object, and at runtime return boxed primitives: instances of Integer, Double, Boolean, etc.
You could explore an enum type as a way to classify the type you end up with. You don't say what you want to use it for, so this may not be best, but it could be done in a way that handles the requirements you do give.
public class ClassifiedType
{
public enum ClassifiedTypeType { INTEGER, FLOAT, STRING, BOOLEAN };
ClassifiedTypeType typeType = null;
int integerValue;
float floatValue;
String stringValue;
boolean booleanValue;
public ClassifiedType(int i) { integerValue = i; typeType = ClassifiedTypeType.INTEGER; }
public ClassifiedType(float f) { floatValue = f; typeType = ClassifiedTypeType.FLOAT; }
// etc.
public int getIntegerValue()
{
if (typeType != ClassifiedTypeType.INTEGER)
{
throw new IllegalArgumentException("Attempting getInteger on type of " + this.toString());
}
else
{
return integerValue;
}
}
// do gets for other types similarly.
public static ClassifiedType getClassifiedType(String string)
{
// parse the string, determine which type you want,
// instantiate a ClassifiedType with its value and
// and type, and return it.
}
}
Other classes can use the ClassifiedTypeType (hopefully with a better name) to determine what kind of value to get from it, to the extent they need that.
Anyway, it beats returning Object and then having to use instanceof all over the place to figure out what you're dealing with, and this extends to non-primitives if you ever need that.
A single Java method cannot return multiple types. This is because Java is a strongly typed language.
There are a few different ways to accomplish this. If you'd like to go the constructor route as mentioned in the OP, it would look something like this:
public class Demo(){
Demo(String str){
// Do something...
}
Demo(int newInt){
// Do something...
}
// Other constructors for other types here
}
public double delhi(Integer a)
{
return (int)a;
}
In case you do not get it, look at the return type of the method
The return type declared on a method is used to allocate a memory on the stack to store the return value. Here, by declaring return type as double compiler will allocate more space (64-bit) than required by the actual return value, an int (32-bit). Therefore, there is no loss of data expected on this (up)conversion. Therfore, both compiler and runtime, does not complain and it works. Try the opposite, set return type as int and return a long or double. You will get compiler error because there will be potential of data corruption.
Because, an int can fit into a double. its called Widening Primitive Conversion.
I have an issue with Java cast long type to Enum's type.
I'm using this code :
public enum RPCPacketDataType {
PT_JSON(1),
PT_BINARY(2);
private int value;
RPCPacketDataType(int i){
this.value=i;
}
public int getNumericType(){
return value;
}
}
static RPCPacketDataType tmpPacket_packetType;
And I need to do something like this :
case 2:
{
long intVal = Long.parseLong(thisPart);
if(intVal == 0){
isBad = true; break;
}
tmpPacket_packetType=intVal;
break;
}
where thisPart is just a string : String thisPart;
And the error says : Type mismatch: cannot convert from long to RPCCommucatorDefines.RPCPacketDataType
Any suggestions how to fix that?
You need to write a method, probably in RPCPacketDataType:
public static RPCPacketDataType valueOf(int value) {
...
}
Then call that from your case statement. Given that the value can only be an integer, you should almost certainly be using Integer.parseInt instead of Long.parseLong.
How you implement the valueOf method is up to you - you could iterate through the EnumSet of all values trying to find a match, or create a HashMap from Integer to RPCPacketDataType, or potentially just an array (with validation). It will depend on what's in your enum, and how many values there are to look through.
Note that you should also consider what to do if valueOf is passed a value which doesn't correspond to any enum value - one option is to return null (and probably test for that explicitly in the calling code); another is to throw an exception.
How do I write a method which returns a primitive datatype value when inside the method it has an if statement which returns a different datatype depending on the result?
int minimum = 5;
int students = 4;
int studentGrades = 100;
public double getAverage(){
if(students >= minimum){
return studentGrades / students;
}
else {
System.out.println(null, "Sorry, you don't have enough students.");
return false;
}
}
You can't really return two different primitive types from the same method. With reference types you could return Object, that that isn't a good idea anyway.
Your return false looks like an error condition, so you might think about throwing an exception here:
public double getAverage(){
if(students >= minimum){
return studentGrades / students;
}
else {
throw new IllegalStateException("not enough students");
}
}
In the example you've given, you should throw an exception - the state of the object isn't valid for the method call, basically. You might want to use IllegalStateException for this, or choose a different type of exception. (That exception extends RuntimeException, so it isn't a checked exception. That may or may not appropriate for your real use case.)
(As an aside, the division in your sample code won't do what you want either - you should cast one of the operands to double if you want it to execute floating point division instead of integer division.)
public Object getAverage()
but then you should check the return class
You can as example return a composite object that contains the score and a flag for success.
Or in the above version you could return Double.NaN to indicate the failure. Or as others have suggested throw an Exception in case of failure.
I'm no Java expert but I think the good practice here is to throw an exception if you have less than the required amount of students. If you must return 2 completely different values I suggest you encapsulate them in a class of your own.
A java method can have only one return type. So you should try some other approche in handling this situation. As others above have pointed out you could throw a exception. Or you could use a nullable data type, and return null when this special condition is true. But this is ugly and is not recommended.