Java: Dynamically cast Object reference to reference's class? - java

Is it possible to cast a variable using a different variable instead of using the name of a class?
Here is functioning code:
Object five = new Integer(5);
int six = (Integer) five + 1;
I would love to replace that second line with
int six = five + 1;
but I can't, so could i do something like one of these alternatives:
int six = (foo) five + 1;
int six = foo(five) + 1;
int six = foo.cast(five) + 1;
??
why i want to do this
I have a Map with keys of a custom enum, and with values of type String, Integer, Double, etc.
I would like to perform class-specific operations on map entry values without hard-coding the cast class.
example
enum keyEnum { height, color; }
public static void main(String[] args) {
Map<keyEnum, Object> map= new HashMap();
String value1 = "red";
Double value2 = 3.2;
map.put(keyEnum.color, value1);
map.put(keyEnum.height, value2);
double x = (Double) map.get(keyEnum.height) + 10.5;
}
I would really like to avoid having to hard-code that (Double) in the last line. Have found no solutions so far, only indications that it might not be possible.
I'm using this setup for a program that needs to write and read and write large csv files. I would like a way for Java to automatically cast variables appropriately so I don't have to remember or code the class of every column type.
I have an enum of all the column titles which i use as keys for maps that store the column's variables. This is to avoid hard-coding the array index for each column (after row.split(",")) which is a maintenance nightmare. I'm open to better approaches to this

You are not using Java as it was intended so it's going to be slow, unsafe and ugly. What you should do is
class MyType { double height; String color; }
public static void main(String[] args) {
MyType mt = new MyType();
mt.color = "red";
mt.height = 3.2;
double x = mt.height;
// to iterate over the fields
for(Field field: MyType.class.getDeclaredFields()) {
System.out.println(field.getName() + "= "+ field.get(mt));
}
}
This will be much safer with compile time checks, use less code and it will use far less memory and CPU.

Store the classtype in a variable, and leverage the cast method.
Class<T> cls and cls.cast()

Related

How to define multiple variables in single statement

In Python, I can define two variables with an array in one line.
>>>[a,b] = [1,2]
>>>a
1
>>>b
2
How do I do the same thing in Java?
I have a couple of variables in class PCT which type is final. Is there a way to define them in one line in a Python like fashion? The following format clearly does not work in Java. I could define them separately, but it will call the parseFile method twice which I want to avoid.
public class PCT {
final int start;
final int stop;
public PCT (File file) {
//......
//......
// the following statement does not compile
[start, stop] = parseFile(file);
}
public int[] parseFile(File f) {
int[] aa = new int[2];
// ....
// ....
return aa;
}
}
You can define multiple variables like this :
double a,b,c;
Each variable in one line can also be assigned to specific value too:
double a=3, b=5.2, c=3.5/3.5;
One more aspect is, while you are preparing common type variable in same line then from right assigned variables you can assign variable on left, for instance :
int a = 4, b = a+1, c=b*b;
Noticed, you can also practice arithmetic operations on variable by remaining in the same line.
This is not possible, but you also don't need to call parseFile twice.
Write your code like this:
int [] temp = parseFile(file);
start = temp[0];
stop = temp[1];
Python (I believe) supports multiple return values. Java obeys C conventions, and so doesn't permit it. Since that isn't part of the language, the syntax for it isn't either, meaning slightly gross hacks like the temp array are needed if you're doing multiple returns.
When declaring several variables of the same type, you can do the following:
int a = 1, b = 2, c = 3; //etc.
If you literaly mean line; as long as you place a semicolon in between two statements, they are executed as if there is a new line in between so you can call:
a = 1; b = 2;
You can even compress an entire file into a oneliner, by removing comment (that scope to the end of the line). Spacing (space, tab, new line,...) is in general removed from the Java files (in memory) as first step in the Java compiler.
But you are probably more interested in a singe statement. Sytax like [start, stop] = parseFile(file); is not supported (at least not for now). You can make a onliner:
int[] data = parseFile(file); start = data[0]; stop = data[1];
Maybe this is what you're looking for:
int array[] = {1,2};
Java array assignment (multiple values)
If you're looking to explicitly assign to each element, I don't think you can do that within one assignment, as a similar concept with the 2-d example below. Which seems like what you want as Jeremy's answers specifies.
Explicitly assigning values to a 2D Array?
Maybe
public class PCT
{
final Point pos; // two ints!
public PCT (File file)
{
pos = parseFile(file);
}
public int[] parseFile(File f)
{
Point aa = new Point();
// ....
// ....
return aa;
}
}

GWT. Create primitive (no- referencable) Integer variable

In my class, I have field int count. I want to create a new variable according to value of count variable, like this: int a = new Integer(count). But when I update count variable: count++, then variable a also gets updated. So how to create non-referencing int variable?
You can't do this with Java. Your closest bet would be to create an enclosing class with a single int, and refer to that instead:
class MutableInteger {
public int value;
}
Then, later:
MutableInteger a = new MutableInteger();
a.value = 5;
MutableInteger b = a;
b.value++;
a.value++;
//since a.value is the same primitive as b.value, they are both 7
But: this breaks a bunch of commonly-accepted best practices in Java. You might look for an alternative way to solve whatever your real problem is.
The situation you've described can't really happen.
Try this code:
int count = 15;
int a = new Integer(count);
count++;
Window.alert("a is "+ a + " and count is " + count);
count is updated and a isn't. So it means you have error somewhere else.
Try the following:
int a = count + 0;
Your problem is somewhat misguided. Here is why:
In Java, the primitive values, when copied, their references are not copied.
look to your code and seek where you are doing an additional step.
The constructor of Integer uses this:
this.integer = integer;

How to avoid unsafe cast warnings with Java Generics

I'm quite new to Java Generics. But I've read a lot of summary links and examples. But I cannot get the simplest method right. I hope somenoe can help:
I want to create a HashMap which maps one undefined Object to another one. Both objects may one of String or Integer.
So I wrote this:
private final HashMap<L, R> left2Right = new HashMap<L, R>();
Extractor<?> extLeft = Extractor.getInstance(0);
Extractor<?> extRight = Extractor.getInstance(1);
L leftVal = extLeft.extract(d, i);
R rightVal = extRight.extract(d, i);
this.left2Right.put(leftVal, rightVal);
So far so good... But I have problems implementing the extractor-objects. They are instanciated by a factory pattern. I did it like this (simplyfied):
abstract class Extractor<E> {
abstract E extract(DTable source, int row);
static <E> Extractor<E> getInstance(int type) {
if(type == 0)
return new IntExtractor();
else
return new StringExtractor();
}
}
class IntExtractor extends Extractor<Integer> {
#Override
Integer extract(DTable source, int row) {
int value = 5;
return new Integer(value);
}
}
class StringExtractor extends Extractor<String> {
#Override
String extract(DTable source, int row) {
String retVal = "hello";
return retVal;
}
}
It compiles, but I get Unsave cast warnings on casting the Integer/String to E. What am I doing wrong? I know, I can simply supress the warnings. But I thought exactly this should be the advantage of Java generics? I cannot make this cast save, because I dont know, which type 'E' really "is"...
Or am I doing something basically wrong?
Note:
I edited my code to a "new" question after I used some information from the first answer...
Your extractors aren't really generic at all. It sounds like you want something like:
public interface Extractor<P> {
P extract(DTable source, int row);
}
but then make the implementations non-generic:
class IntExtractor implements Extractor<Integer> {
Integer extract(DTable source, int row) {
int value = 5;
return new Integer(value);
}
}
Fundamentally your current code is broken, in that I could write:
IntExtractor<String> extractor = new IntExtractor<String>();
String x = extractor.extract(...);
... that would obviously fail, but only at execution time.
I'd say you're doing something basically wrong. If it is an IntExtractor and a StringExtractor, you don't need generics. Just define methods
Integer extract(DTable source, int row)
and
String extract(DTable source, int row)
The Problem isn't your code per-se. The task itself cannot be solved without unsafe casts. Read your own sentence again:
I want to create a HashMap which maps one undefined Object to
another one. Both objects may one of String or Integer.
Java Generics cannot solve this problem for you, because you have to know the type beforehand, otherwise you have to cast.
To be honest, I do not know what you want to achieve with the code you posted, but If you want to use a HashMap, you can do it like this:
private final HashMap<String, Integer> left2Right = new HashMap<String, Integer>();
left2Right.put("one", 1);
int numberOne = left2Right.get("one");
In this case you do not have to cast the values, because the HashMap has String keys and Integer values. If you want to put different types as values, you have to use a supertype of all values. This super type might be Object, the root of the hierarchy. But in those cases you have to cast - because you do not know what kind of object the value is.
private final HashMap<String, Integer> left2Right = new HashMap<String, Object>();
left2Right.put("one", 1);
left2Right.put("two", new Date());
// Because the compiler cannot know that type "one" might be, this isn't allowed and you have to cast the value. It might be anything - in this example Date or Integer.
int numberOne = left2Right.get("one");
I hope that helps.
Both P and E seem not to be used for the input of the extractors so why are you even having them? Just return int and String and be done with it.

How to check type of variable in Java?

How can I check to make sure my variable is an int, array, double, etc...?
Edit: For example, how can I check that a variable is an array? Is there some function to do this?
Java is a statically typed language, so the compiler does most of this checking for you. Once you declare a variable to be a certain type, the compiler will ensure that it is only ever assigned values of that type (or values that are sub-types of that type).
The examples you gave (int, array, double) these are all primitives, and there are no sub-types of them. Thus, if you declare a variable to be an int:
int x;
You can be sure it will only ever hold int values.
If you declared a variable to be a List, however, it is possible that the variable will hold sub-types of List. Examples of these include ArrayList, LinkedList, etc.
If you did have a List variable, and you needed to know if it was an ArrayList, you could do the following:
List y;
...
if (y instanceof ArrayList) {
...its and ArrayList...
}
However, if you find yourself thinking you need to do that, you may want to rethink your approach. In most cases, if you follow object-oriented principles, you will not need to do this. There are, of course, exceptions to every rule, though.
Actually quite easy to roll your own tester, by abusing Java's method overload ability. Though I'm still curious if there is an official method in the sdk.
Example:
class Typetester {
void printType(byte x) {
System.out.println(x + " is an byte");
}
void printType(int x) {
System.out.println(x + " is an int");
}
void printType(float x) {
System.out.println(x + " is an float");
}
void printType(double x) {
System.out.println(x + " is an double");
}
void printType(char x) {
System.out.println(x + " is an char");
}
}
then:
Typetester t = new Typetester();
t.printType( yourVariable );
a.getClass().getName() - will give you the datatype of the actual object referred to by a, but not the datatype that the variable a was originally declared as or subsequently cast to.
boolean b = a instanceof String - will give you whether or not the actual object referred to by a is an instance of a specific class.
Again, the datatype that the variable a was originally declared as or subsequently cast to has no bearing on the result of the instanceof operator.
I took this information from:
How do you know a variable type in java?
This can happen. I'm trying to parse a String into an int and I'd like to know if my Integer.parseInt(s.substring(a, b)) is kicking out an int or garbage before I try to sum it up.
By the way, this is known as Reflection. Here's some more information on the subject: http://docs.oracle.com/javase/tutorial/reflect/
Just use:
.getClass().getSimpleName();
Example:
StringBuilder randSB = new StringBuilder("just a String");
System.out.println(randSB.getClass().getSimpleName());
Output:
StringBuilder
You may work with Integer instead of int, Double instead of double, etc. (such classes exists for all primitive types).
Then you may use the operator instanceof, like if(var instanceof Integer){...}
Well, I think checking the type of variable can be done this way.
public <T extends Object> void checkType(T object) {
if (object instanceof Integer)
System.out.println("Integer ");
else if(object instanceof Double)
System.out.println("Double ");
else if(object instanceof Float)
System.out.println("Float : ");
else if(object instanceof List)
System.out.println("List! ");
else if(object instanceof Set)
System.out.println("Set! ");
}
This way you need not have multiple overloaded methods. I think it is good practice to use collections over arrays due to the added benefits. Having said that, I do not know how to check for an array type. Maybe someone can improve this solution. Hope this helps!
P.S Yes, I know that this doesn't check for primitives as well.
The first part of your question is meaningless. There is no circumstance in which you don't know the type of a primitive variable at compile time.
Re the second part, the only circumstance that you don't already know whether a variable is an array is if it is an Object. In which case object.getClass().isArray() will tell you.
I did it using: if(x.getClass() == MyClass.class){...}
I wasn't happy with any of these answers, and the one that's right has no explanation and negative votes so I searched around, found some stuff and edited it so that it is easy to understand. Have a play with it, not as straight forward as one would hope.
//move your variable into an Object type
Object obj=whatYouAreChecking;
System.out.println(obj);
// moving the class type into a Class variable
Class cls=obj.getClass();
System.out.println(cls);
// convert that Class Variable to a neat String
String answer = cls.getSimpleName();
System.out.println(answer);
Here is a method:
public static void checkClass (Object obj) {
Class cls = obj.getClass();
System.out.println("The type of the object is: " + cls.getSimpleName());
}
Basically , For example :
public class Kerem
{
public static void main(String[] args)
{
short x = 10;
short y = 3;
Object o = y;
System.out.println(o.getClass()); // java.lang.Short
}
}
None of these answers work if the variable is an uninitialized generic type
And from what I can find, it's only possible using an extremely ugly workaround, or by passing in an initialized parameter to your function, making it in-place, see here:
<T> T MyMethod(...){ if(T.class == MyClass.class){...}}
Is NOT valid because you cannot pull the type out of the T parameter directly, since it is erased at runtime time.
<T> void MyMethod(T out, ...){ if(out.getClass() == MyClass.class){...}}
This works because the caller is responsible to instantiating the variable out before calling. This will still throw an exception if out is null when called, but compared to the linked solution, this is by far the easiest way to do this
I know this is a kind of specific application, but since this is the first result on google for finding the type of a variable with java (and given that T is a kind of variable), I feel it should be included
var.getClass().getSimpleName()
Let's take a example
String[] anArrayOfStrings = { "Agra", "Mysore", "Chandigarh", "Bhopal" };
List<String> strList = Arrays.asList(anArrayOfStrings);
anArrayOfStrings.getClass().getSimpleName() //res => String[]
strList.getClass().getSimpleName() // res => ArrayList
You can check it easily using Java.lang.Class.getSimpleName() Method Only if variable has non-primitive type. It doesnt work with primitive types int ,long etc.
reference - Here is the Oracle docs link
I hit this question as I was trying to get something similar working using Generics. Taking some of the answers and adding getClass().isArray() I get the following that seems to work.
public class TypeTester <T extends Number>{
<T extends Object> String tester(T ToTest){
if (ToTest instanceof Integer) return ("Integer");
else if(ToTest instanceof Double) return ("Double");
else if(ToTest instanceof Float) return ("Float");
else if(ToTest instanceof String) return ("String");
else if(ToTest.getClass().isArray()) return ("Array");
else return ("Unsure");
}
}
I call it with this where the myArray part was simply to get an Array into callFunction.tester() to test it.
public class Generics {
public static void main(String[] args) {
int [] myArray = new int [10];
TypeTester<Integer> callFunction = new TypeTester<Integer>();
System.out.println(callFunction.tester(myArray));
}
}
You can swap out the myArray in the final line for say 10.2F to test Float etc
public static void chkType(Object var){
String type = var.getClass().toString();
System.out.println(type.substring(16));
//assertEquals(type,"class java.lang.Boolean");
//assertEquals(type,"class java.lang.Character");
//assertEquals(type,"class java.lang.Integer");
//assertEquals(type,"class java.lang.Double");
}
A simple solution I found was the following rather than wondering about fire command. Also, you can check this article
public class DataTypeCheck
{
public static void main(String[] args)
{
String jobTitle = "Agent";
int employeeId = 7;
double floating= 10.0;
String bond = jobTitle + employeeId;
System.out.println(((Object)floating).getClass().getSimpleName());
System.out.println(((Object)employeeId).getClass().getSimpleName());
System.out.println(((Object)jobTitle).getClass().getSimpleName());
System.out.println(((Object)bond).getClass().getSimpleName());
}
}
Output:
Double
Integer
String
String

How to cast an Object to an int

How can I cast an Object to an int in java?
If you're sure that this object is an Integer :
int i = (Integer) object;
Or, starting from Java 7, you can equivalently write:
int i = (int) object;
Beware, it can throw a ClassCastException if your object isn't an Integer and a NullPointerException if your object is null.
This way you assume that your Object is an Integer (the wrapped int) and you unbox it into an int.
int is a primitive so it can't be stored as an Object, the only way is to have an int considered/boxed as an Integer then stored as an Object.
If your object is a String, then you can use the Integer.valueOf() method to convert it into a simple int :
int i = Integer.valueOf((String) object);
It can throw a NumberFormatException if your object isn't really a String with an integer as content.
Resources :
Oracle.com - Autoboxing
Oracle.com - Primitive Data types
On the same topic :
Java: What's the difference between autoboxing and casting?
Autoboxing: So I can write: Integer i = 0; instead of: Integer i = new Integer(0);
Convert Object into primitive int
Scenario 1: simple case
If it's guaranteed that your object is an Integer, this is the simple way:
int x = (Integer)yourObject;
Scenario 2: any numerical object
In Java Integer, Long, BigInteger etc. all implement the Number interface which has a method named intValue. Any other custom types with a numerical aspect should also implement Number (for example: Age implements Number). So you can:
int x = ((Number)yourObject).intValue();
Scenario 3: parse numerical text
When you accept user input from command line (or text field etc.) you get it as a String. In this case you can use Integer.parseInt(String string):
String input = someBuffer.readLine();
int x = Integer.parseInt(input);
If you get input as Object, you can use (String)input, or, if it can have an other textual type, input.toString():
int x = Integer.parseInt(input.toString());
Scenario 4: identity hash
In Java there are no pointers. However Object has a pointer-like default implementation for hashCode(), which is directly available via System.identityHashCode(Object o). So you can:
int x = System.identityHashCode(yourObject);
Note that this is not a real pointer value. Objects' memory address can be changed by the JVM while their identity hashes are keeping. Also, two living objects can have the same identity hash.
You can also use object.hashCode(), but it can be type specific.
Scenario 5: unique index
In same cases you need a unique index for each object, like to auto incremented ID values in a database table (and unlike to identity hash which is not unique). A simple sample implementation for this:
class ObjectIndexer {
private int index = 0;
private Map<Object, Integer> map = new WeakHashMap<>();
// or:
// new WeakIdentityHashMap<>();
public int indexFor(Object object) {
if (map.containsKey(object)) {
return map.get(object);
} else {
index++;
map.put(object, index);
return index;
}
}
}
Usage:
ObjectIndexer indexer = new ObjectIndexer();
int x = indexer.indexFor(yourObject); // 1
int y = indexer.indexFor(new Object()); // 2
int z = indexer.indexFor(yourObject); // 1
Scenario 6: enum member
In Java enum members aren't integers but full featured objects (unlike C/C++, for example). Probably there is never a need to convert an enum object to int, however Java automatically associates an index number to each enum member. This index can be accessed via Enum.ordinal(), for example:
enum Foo { BAR, BAZ, QUX }
// ...
Object baz = Foo.BAZ;
int index = ((Enum)baz).ordinal(); // 1
Assuming the object is an Integer object, then you can do this:
int i = ((Integer) obj).intValue();
If the object isn't an Integer object, then you have to detect the type and convert it based on its type.
#Deprecated
public static int toInt(Object obj)
{
if (obj instanceof String)
{
return Integer.parseInt((String) obj);
} else if (obj instanceof Number)
{
return ((Number) obj).intValue();
} else
{
String toString = obj.toString();
if (toString.matches("-?\d+"))
{
return Integer.parseInt(toString);
}
throw new IllegalArgumentException("This Object doesn't represent an int");
}
}
As you can see, this isn't a very efficient way of doing it. You simply have to be sure of what kind of object you have. Then convert it to an int the right way.
You have to cast it to an Integer (int's wrapper class). You can then use Integer's intValue() method to obtain the inner int.
Answer:
int i = ( Integer ) yourObject;
If, your object is an integer already, it will run smoothly. ie:
Object yourObject = 1;
// cast here
or
Object yourObject = new Integer(1);
// cast here
etc.
If your object is anything else, you would need to convert it ( if possible ) to an int first:
String s = "1";
Object yourObject = Integer.parseInt(s);
// cast here
Or
String s = "1";
Object yourObject = Integer.valueOf( s );
// cast here
I use a one-liner when processing data from GSON:
int i = object != null ? Double.valueOf(object.toString()).intValue() : 0;
If the Object was originally been instantiated as an Integer, then you can downcast it to an int using the cast operator (Subtype).
Object object = new Integer(10);
int i = (Integer) object;
Note that this only works when you're using at least Java 1.5 with autoboxing feature, otherwise you have to declare i as Integer instead and then call intValue() on it.
But if it initially wasn't created as an Integer at all, then you can't downcast like that. It would result in a ClassCastException with the original classname in the message. If the object's toString() representation as obtained by String#valueOf() denotes a syntactically valid integer number (e.g. digits only, if necessary with a minus sign in front), then you can use Integer#valueOf() or new Integer() for this.
Object object = "10";
int i = Integer.valueOf(String.valueOf(object));
See also:
Inheritance and casting tutorial
int i = (Integer) object; //Type is Integer.
int i = Integer.parseInt((String)object); //Type is String.
Can't be done. An int is not an object, it's a primitive type. You can cast it to Integer, then get the int.
Integer i = (Integer) o; // throws ClassCastException if o.getClass() != Integer.class
int num = i; //Java 1.5 or higher
You can't. An int is not an Object.
Integer is an Object though, but I doubt that's what you mean.
If you mean cast a String to int, use Integer.valueOf("123").
You can't cast most other Objects to int though, because they wont have an int value. E.g. an XmlDocument has no int value.
I guess you're wondering why C or C++ lets you manipulate an object pointer like a number, but you can't manipulate an object reference in Java the same way.
Object references in Java aren't like pointers in C or C++... Pointers basically are integers and you can manipulate them like any other int. References are intentionally a more concrete abstraction and cannot be manipulated the way pointers can.
int[] getAdminIDList(String tableName, String attributeName, int value) throws SQLException {
ArrayList list = null;
Statement statement = conn.createStatement();
ResultSet result = statement.executeQuery("SELECT admin_id FROM " + tableName + " WHERE " + attributeName + "='" + value + "'");
while (result.next()) {
list.add(result.getInt(1));
}
statement.close();
int id[] = new int[list.size()];
for (int i = 0; i < id.length; i++) {
try {
id[i] = ((Integer) list.get(i)).intValue();
} catch(NullPointerException ne) {
} catch(ClassCastException ch) {}
}
return id;
}
// enter code here
This code shows why ArrayList is important and why we use it. Simply casting int from Object. May be its helpful.
For Example Object variable; hastaId
Object hastaId = session.getAttribute("hastaID");
For Example Cast an Object to an int,hastaID
int hastaID=Integer.parseInt(String.valueOf(hastaId));
Refer This code:
public class sample
{
public static void main(String[] args)
{
Object obj=new Object();
int a=10,b=0;
obj=a;
b=(int)obj;
System.out.println("Object="+obj+"\nB="+b);
}
}
so divide1=me.getValue()/2;
int divide1 = (Integer) me.getValue()/2;
We could cast an object to Integer in Java using below code.
int value = Integer.parseInt(object.toString());
If you want to convert string-object into integer...
you can simply pass as:
int id = Integer.valueOf((String) object_name);
Hope this will be helpful :-)
Integer x = 11
int y = x.intValue();
System.out.println("int value"+ y);
Finally, the best implementation for your specification was found.
public int tellMyNumber(Object any) {
return 42;
}
first check with instanceof keyword . if true then cast it.

Categories