Object o = myC.getConstructor(short.class).newInstance(myC.cast(pPrim));
Is there a way avoid hard coding "short.class
" and instead get a literal from pPrim
?
I got the idea for using "short.class
" from the answer in Create new object using reflection?
T o = ...
(for a Byte or a Short, e.g.) instead of Object o = ...
? I think my method is nearly identical to the one found at the end of Class Literals as Runtime-Type Tokens.
I'm studying the book OCA Java SE 7: Programmer 1 Study Guide by Finegan and Liguori in preparation for 1Z0-803. So I'm practicing code a lot. While practicing, I wrote a class hoping to see what's going on inside primitives when cast from a char. I listed the code below ... if you take a look please focus on the methods byteToBinaryString, shortToBinaryString, and primitiveToBinaryString ... that's where my question arose.
import java.util.TreeMap;
import java.util.Set;
public class StackoverflowQuestion {
// I wrote this 1st
public static String byteToBinaryString(byte pByte) {
int primLength = 8;
int count = 0;
String s = "";
while ( count++ < primLength ) {
byte sm = (byte) (pByte & 0x01);
pByte >>= 1;
s = sm + s;
if ( count % 4 == 0 && count != primLength ) {
s = " " + s;
}
}
return s;
}
// Then I cloned byteToBinaryString to this and had the thought,
// I shouldn' have to repeat this
public static String shortToBinaryString(short pShort) {
int primLength = 16;
int count = 0;
String s = "";
while ( count++ < primLength ) {
short sm = (short) (pShort & 0x0001);
pShort >>= 1;
s = sm + s;
if ( count % 4 == 0 && count != primLength ) {
s = " " + s;
}
}
return s;
}
// So I cloned shortToBinaryString, modifidied to this and ...
public static <T extends Number> String primitiveToBinaryString(T pPrim) {
int primLength = 16;
int count = 0;
String className = pPrim.getClass().getName();
try {
Class<?> myC = Class.forName(className);
// ... got stuck here
Object o = myC.getConstructor(short.class).newInstance(myC.cast(pPrim));
System.out.println(pPrim + "<--pPrim.equals(o)-->" + pPrim.equals(o) + "<--" + o);
} catch ( Exception e ) {
System.out.println("Caught exception: " + e);
}
String s = "";
while ( count++ < primLength ) {
//T sm = new Class<T>(pPrim.intValue() & 0x0001);
//pPrim >>= 1;
//s = sm + s;
if ( count % 4 != 0 && count != primLength ) {
s = "-" + s;
}
}
return s;
}
public static void main ( String[] args ) {
// exercise byteToBinaryString
for ( int i = 0; i < 256; i++ ) {
char cByte = (char) i;
byte b1 = (byte) cByte;
System.out.printf( "char(%c): charValue(%05d): bin(%s): dec(%+6d)\n", cByte, (int) cByte, byteToBinaryString(b1), b1 );
}
// exercise shortToBinaryString
// please ignore my use of TreeMap, just figuring out how it works
TreeMap<Integer, String> charsTM = new TreeMap<Integer, String>();
charsTM.put(00000, "00000");
charsTM.put(00001, "00001");
charsTM.put(32766, "32766");
charsTM.put(32767, "32767");
charsTM.put(32768, "32768");
charsTM.put(32769, "32769");
charsTM.put(65535, "65535");
short s1 = 32767;
char ch1 = 32768;
Set<Integer> charKeys = charsTM.keySet();
// loop through the boundary values I selected to show what's going on in memory
for ( Integer i : charKeys ) {
ch1 = (char) i.intValue();
s1 = (short) ch1;
System.out.printf( "char(%c): charValue(%05d): bin(%s): dec(%+6d)\n", ch1, (int) ch1, shortToBinaryString(s1), s1 );
}
// exercise primitiveToBinaryString
primitiveToBinaryString( (byte) 127 );
primitiveToBinaryString( (short) 32767 );
primitiveToBinaryString( (int) 2147483647);
primitiveToBinaryString( 2147483648L);
primitiveToBinaryString( 2147483648F);
primitiveToBinaryString( 2147483648D);
}
}
A class literal is an expression consisting of the name of a class, interface, array, or primitive type followed by a . and the token class . The type of a class literal is Class .
We can use newInstance() method on the constructor object to instantiate a new instance of the class. Since we use reflection when we don't have the classes information at compile time, we can assign it to Object and then further use reflection to access it's fields and invoke it's methods.
A couple of things:
This could be cleaned up a little:
String className = pPrim.getClass().getName();
Class<?> myC = Class.forName(className);
//Can just do
Class<?> myC = pPrim.getClass();
Also, if you are looking for a single argument constructor that takes a primitive value you could do:
public Constructor<?> getPrimitiveSingleArgConstructor(Class<?> myC) {
for( Constructor<?> constructor : myC.getConstructors() ) {
if( constructor.getParameterTypes().length == 1 ) {
Class<?> paramType = constructor.getParameterTypes()[0];
if (paramType.isPrimitive()) {
return constructor;
}
}
}
}
Finally, if you are trying to convert a number to an binary string and you are only working with integer numbers (I'm assuming you are) you could always cast the number upwards to a long and convert that to a binary string.
long integralValue = pPrim.longValue();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With