2

Background: I have an assignment where I'm going to pass information through sockets to a very limited extent. It can be a maximum of 10 bytes per message and I was thinking I'm gonna send just one byte (since one byte is enough to signal 256 different states in the protocol). Now I start to dig around looking for information about this and I run into a lot of questions. Please correct me where my assumptions are wrong and answer my literal questions if you can.

So there is the primitive data type byte (which is basically a number between -128 and 127 inclusive, right?). If I use

byte b = 125;
System.out.println(b);

...I get the correct number printed to the console and if I try to assign values outside the limits, the compiler complains.

Then we have the class Byte which apparently creates a Byte object from a byte data type (or int as it says in the API):

Byte b = new Byte(20);
System.out.println(b);

This also produces the expected result and 20 is printed to the console and if I try to use a higher number than 127, the compiler complains.

1. What is the difference between data type byte and class Byte? Is it mainly because the class offers a lot of methods like class Integer does for type int?

The next snippet produces weird results (to me):

import java.io.*;

public class ByteTest {

    public static void main(String[] args) {

        DataInputStream in = new DataInputStream(System.in);

        try {
            byte d;
            while((d = in.readByte()) != 0) {
                System.out.println(d);
            }
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        System.exit(0);
        }
    }

2. The input is read and out comes the interpretation of the input as an ASCII character in decimal form (for example, 1 returns 49), followed by two more rows with numbers 13 and 10. why is this?

(It doesn't matter if I declare d as a Byte or byte, the result is the same and I've mixed around with getting the value from Byte b instead and so on but these three lines (or more) are always the result and all I want is the input coming right back at me)

Basically I'm a bit confused by this but in the end, all I want is a reasonable way for these single bytes to be sent and when I send 34, I want the other side to received 34, nothing else.

3. Let's say I refrain from using the class Byte and just want to send a type byte over a stream. All regular streams and readers seem to read nothing less than an int (which I assume means that they will block until they have at least two bytes of input where as I will only send one). Am I forced to use DataInputStream and DataOutputStream where I have to wrap the type byte in an object Byte or are there other ways?

All of this has made me doubt whether I can trust that an object Byte really just amounts to a byte of data and nothing more... I'm confused :(

Thanks in advance!

fast-reflexes
  • 4,891
  • 4
  • 31
  • 44
  • 1
    The `Byte` object is simply the class representation of the primitive `byte`. The JVM uses [autoboxing](http://docs.oracle.com/javase/1.5.0/docs/guide/language/autoboxing.html) to make the two interchangeable in certain cases. – FThompson Dec 02 '12 at 17:36

3 Answers3

5
  1. Yes. The Byte wrapper also allows representing a nullable byte, or storing byte values into collections and maps, for example.

  2. You send text to the DataInputStream, and this text is encoded to bytes using your platform default encoding. Suppose it's ASCII, the first character will thus be encoded to a byte, then \r and \n are sent, which are also encoded using ASCII. So the 3 bytes you read are the ASCII-encoded values of your char + \r\n.

  3. The javadoc explains what InputStream.read() does. It reads one byte, and converts it to an int between 0 and 255, in order to distinguish between the byte -1 and the -1 which means "end of stream". To get a byte from the returned int, check it isn't -1 (which means end of stream), and cast it to a byte: byte b = (byte) readValue;

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • 1. Thanks, got it! 2. I send text to DataInputStream.. so the JVM will always interpret stuff from System.in as text, I can't make it interpret it as a byte number straight up? I would have to convert it inside the program before printing it then? So basically what happens is that System.in doesn't provide the input to the DataInputStream until I hit enter and then the DataInputStream has three bytes to work through keeping it busy for three loops in the while loop? – fast-reflexes Dec 02 '12 at 17:48
  • 3. Ok got it, maybe this is outside of my knowledge but I looked up the InputStream earlier and I didn't understand how to use it since it's an abstract class and the InputStreamReader doesn't have a method for reading just one byte... so basically all I could find was DataInputStream... but maybe there's a way to use the InputStream that I don't know of... – fast-reflexes Dec 02 '12 at 17:48
  • InputStream and all its subclasses are meant to read binary data (bytes). Reader and all its subclasses are meant to read textual data (chars). You won't find any method to read a byte in a Reader, since it's not supposed to read bytes, but chars. It will be obvious how to get an instance of InputStream if you read from something other than System.in, which is not supposed to contain bytes, but text. For example, if you read from a file, you'll use a FileInputSTream. If you read from a Socket, you'll get the socket's InputStream. – JB Nizet Dec 02 '12 at 17:56
  • Ok.. I understand it this way: Basically there is some sort of function in the command line editor that interprets the input and sends it as a stream of bytes at some specific point. Most often, this point is when you hit enter but this can be adjusted in some editors ("raw" mode). The input is interpreted as a signed byte and sent to some sort of OutputStream that results in the InputStream System.in. When System.in reads a byte, it interprets it and returns a int in the range of 0-255. – fast-reflexes Dec 09 '12 at 12:26
  • If I use DataInputStream's readByte, it invokes the underlying InputStream's read() method and then interprets the given int as a signed byte, thus transforming it back to a byte value ranging from -128-127 which was exactly the same byte that the underlying InputStream read and interpreted as an int ranging from 0-255. – fast-reflexes Dec 09 '12 at 12:27
0

There is no need to wrap to object Byte in your case, you mainly need Byte when working with collections.

DataOutPutStream is fine, use method write(int b)

byte b = (byte) 0x03;
DataOutPutStream dos;
// ....
dos.write(b);
AlexWien
  • 28,470
  • 6
  • 53
  • 83
-1

The difference is, as you said, that Byte is a wrapper class to byte. As byte is a primitive, you cannot assing null to any byte variables. In contrast, Byte is an object, so you can assign null.

So:

byte primitiveByte = null; // Compiler error
Byte objectByte = null; // works

As Vulcan said, Byte is autoboxed to byte, which means that if the JVM sees that it can use byte instead of a Byte object, it replaces the occurence with a byte primtive.

user3001
  • 3,437
  • 5
  • 28
  • 54
  • 1
    The JVM uses autoboxing just when it needs to, i. e. a method that has `byte` parameters, but gets invoked with an instance of `Byte`. At least in my understanding of the matter. – mike Jul 11 '13 at 12:47