Größe eines Generischen Typs

Ryu1991

Erfahrenes Mitglied
Hey,
ich schreibe im moment eine Anwendung, bei der Ich viele Informationen über netzwerk verschicken muss, und zwar in Form von byte[].
So kommt es dass ich relativ häufig Zahlen von short, oder int zu byte[] konvertieren muss.
Ist ja von der Logik her kein Problem :

Java:
...
array[0] = my_short / 0x100;
array[1] = my_short % 0x100;

Aber, bei Ints wird das schon ganz schön mühseelig, weswegen ich mir dafür eine Funktion schreiben wollte, ungefähr so:

(Peudocode, ^= hoch in dem fall)
Java:
package Utils;

public class ByteConverter{
	public static <T> byte[] toByteArray(T number){
		short size = sizeof number;
		byte[] new_array = new byte[size];
		
		for(short i = 0;i < size; i++){
			new_array[i] = (byte) ((number % (0x10 ^ (size - i)) / (0x10^(size- i - 2)));
		}
		
		return new_array;
	}
}

Das ganze scheitert jetzt natürlich daran, dass ich kein sizeof, oder etwas vergleichbares gefunden habe.

Deswegen meine Frage an euch, wie kann ich dieses Problem lösen, ohne für short, int und double einzelne Methoden anzulegen?
 
Hi,
du kannst z.B. mit Number arbeiten.
Oder du übergibst ein ? number und suchst dir dann den richtigen Typen mit if-Bedingung raus.
Java:
public static byte[] toByteArray(? number){
        byte[] new_array = new byte[size];
        if(number instanceof ...) {

        } else if(number instanceof ...) {

        }
        return new_array;
    }
Eine andere Möglichkeit wäre, dass du einfach jede Zahl in einen Long-Wert castest. Das würde wahrscheinlich am leichtesten, schnellsten und mit dem wenigsten Aufwand gehen.

Gruß

Fabio
 
Hey, danke schonmal für die Antwort,
Also das mit dem ? sieht zwar cool aus, aber Eclipse sagt mir, dass das nicht geht.
funktioniert instanceof auch mit T oder, oder kommt dann immer false raus, außer ich mache instanceof(T) ?

In Long casten geht nicht, weil ich wenn ich ein short übergebe auch nur ein 2byte großes array zurückmöchte, und kein 8byte großes.
 
hallo Ryu1991
Mein Vorschlag ist das Argument als Typ ArrayList<Byte> zu verwenden, da die ArrayList auch die Methode size() unterstützt. Falls Du ein Array benötigst, kannst Du dann immer noch

Byte[] byteArray = new Byte[list.size()];
byteArray = list.toArray(byteArray);

ausführen, um die ArrayList namens list in ein Byte-Array zu konvertieren.
 
Und wie soll ich dann da nen Int, Short, oder double reinbekommen?
Und wie sieht das Byte-Array aus, wenn ichs zurück kriege, weil das muss ziemlich genauen Regeln unterliegen

Also ich habe jetzt das:

Java:
package Utils;

public class ByteConverter{
	public static <T> byte[] toByteArray(T number){
		short size = 0;
		
		if(number instanceof Double) size = 8;
		if(number instanceof Integer) size = 4;
		if(number instanceof Short) size = 2;
		if(number instanceof Byte) size = 1;
		else{
			String s = "Du hast ByteConverter.toByteArray einen Illegalen Typ übergeben, idiot";
			DebugPrinter.getInstance().println(s);
			throw new Exception(s);
		}
		
		byte[] array = new byte[size];
		
		for(int i = 0; i < size; i++){
			array[i] = (byte) ((number % Math.pow(0x100, size-i)) / Math.pow(0x100, size-i - 1));
		}
	}
}
Aber jetzt funktioniert der Modulo-Operator nicht bei bei Number.
Kann man das vllt irgendwie dynamisch umcasten?
 
Zuletzt bearbeitet von einem Moderator:
Hallo,

schau mal hier:
Java:
package de.tutorials;

import java.nio.ByteBuffer;
import java.util.Arrays;

public class ByteArrayConversionExample {
	public static void main(String[] args) {
		System.out.println(Arrays.toString(toBytes(123))        + " ===> " + fromBytes(toBytes(123), int.class));
		System.out.println(Arrays.toString(toBytes(123L)) 	    + " ===> " + fromBytes(toBytes(123L), long.class));
		System.out.println(Arrays.toString(toBytes((byte)123))  + " ===> " + fromBytes(toBytes((byte)123), byte.class));
		System.out.println(Arrays.toString(toBytes((short)123)) + " ===> " + fromBytes(toBytes((short)123), short.class));
		System.out.println(Arrays.toString(toBytes(123.0D))		+ " ===> " + fromBytes(toBytes(123.0D), double.class));
		System.out.println(Arrays.toString(toBytes(123.0F))		+ " ===> " + fromBytes(toBytes(123.0F), float.class));
	}

	static <T extends Number> byte[] toBytes(T num) {
		if (num instanceof Integer) {
			return ByteBuffer.allocate(inBytes(Integer.SIZE)).putInt(((Integer)num).intValue()).array();
		}else if (num instanceof Short) {
			return ByteBuffer.allocate(inBytes(Short.SIZE)).putShort(((Short)num).shortValue()).array();
		}else if (num instanceof Long) {
			return ByteBuffer.allocate(inBytes(Long.SIZE)).putLong(((Long)num).longValue()).array();
		}else if (num instanceof Double) {
			return ByteBuffer.allocate(inBytes(Double.SIZE)).putDouble(((Double)num).doubleValue()).array();
		}else if (num instanceof Float) {
			return ByteBuffer.allocate(inBytes(Float.SIZE)).putFloat(((Float)num).floatValue()).array();
		}else if(num instanceof Byte){
			return ByteBuffer.allocate(inBytes(Byte.SIZE)).put(((Byte)num).byteValue()).array();
		}else{
			throw new IllegalArgumentException(num +" not supported");
		}
	}

	private static int inBytes(int bits) {
		return bits/Byte.SIZE;
	}
	
	@SuppressWarnings("unchecked")
	static <T extends Number> T fromBytes(byte[] bytes, Class<T> numType){
		ByteBuffer buffer = ByteBuffer.wrap(bytes);
		if(Integer.class.equals(numType) || int.class.equals(numType)){
			return (T)Integer.valueOf(buffer.asIntBuffer().get());
		}else if(Short.class.equals(numType) || short.class.equals(numType)){
			return (T)Short.valueOf(buffer.asShortBuffer().get());
		}else if(Long.class.equals(numType) || long.class.equals(numType)){
			return (T)Long.valueOf(buffer.asLongBuffer().get());
		}else if(Double.class.equals(numType) || double.class.equals(numType)){
			return (T)Double.valueOf(buffer.asDoubleBuffer().get());
		}else if(Float.class.equals(numType) || float.class.equals(numType)){
			return (T)Float.valueOf(buffer.asFloatBuffer().get());
		}else if(Byte.class.equals(numType) || byte.class.equals(numType)){
			return (T)Byte.valueOf(buffer.get());
		}else{
			throw new IllegalArgumentException(numType +" not supported");
		}
	}

}

Ausgabe:
Code:
[0, 0, 0, 123] ===> 123
[0, 0, 0, 0, 0, 0, 0, 123] ===> 123
[123] ===> 123
[0, 123] ===> 123
[64, 94, -64, 0, 0, 0, 0, 0] ===> 123.0
[66, -10, 0, 0] ===> 123.0

Gruß Tom
 
Zurück