简体   繁体   English

Java原始数据类型字节和类Byte

[英]Java primitive data type byte and class Byte

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). 它可以是每个消息最多10个字节,我以为我只发送一个字节(因为一个字节足以在协议中发出256个不同的状态)。 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?). 所以有原始数据类型字节(基本上是介于-128和127之间的数字,对吧?)。 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,它显然是从字节数据类型(或API中的int)创建一个Byte对象:

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. 这也产生了预期的结果,并且20被打印到控制台,如果我尝试使用高于127的数字,编译器会抱怨。

1. What is the difference between data type byte and class Byte? 1.数据类型字节和类字节有什么区别? Is it mainly because the class offers a lot of methods like class Integer does for type int? 是否主要是因为类提供了许多方法,如类Integer为类型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? 2.输入被读取和输出将输入解释为十进制形式的ASCII字符(例如,1返回49),接着是另外两行,数字为13和10.这是为什么?

(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) (如果我将d声明为字节或字节无关紧要,结果是相同的,我已经混合了从字节b获取值,依此类推,但这三行(或更多)始终是结果而我想要的只是输入回到我身边)

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. 基本上我对此有点困惑,但最后,我想要的只是发送这些单个字节的合理方式,当我发送34时,我希望对方收到34,没有别的。

3. Let's say I refrain from using the class Byte and just want to send a type byte over a stream. 3.假设我没有使用类Byte,只想在流上发送一个类型字节。 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). 所有常规流和读取器似乎都只读取一个int(我假设它们会阻塞,直到它们至少有两个字节的输入,因为我只发送一个)。 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? 我是否被迫使用DataInputStreamDataOutputStream ,我必须在对象Byte中包装类型字节,还是有其他方法?

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 :( 所有这一切让我怀疑我是否可以相信一个对象Byte真的只是一个字节的数据而已......我很困惑:(

Thanks in advance! 提前致谢!

  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. 您将文本发送到DataInputStream,并使用您的平台默认编码将此文本编码为字节。 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. 假设它是ASCII,第一个字符将被编码为一个字节,然后发送\\r\\n ,它们也使用ASCII编码。 So the 3 bytes you read are the ASCII-encoded values of your char + \\r\\n . 因此,您读取的3个字节是char + \\r\\n的ASCII编码值。

  3. The javadoc explains what InputStream.read() does. javadoc解释了InputStream.read()作用。 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". 它读取一个字节,并将其转换为0到255之间的int,以便区分字节-1和-1,这意味着“流的结束”。 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; 要从返回的int中获取一个字节,请检查它不是-1(表示流的结尾),并将其byte b = (byte) readValue;转换为字节: byte b = (byte) readValue;

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) DataOutPutStream很好,使用方法write(int b)

byte b = (byte) 0x03;
DataOutPutStream dos;
// ....
dos.write(b);

The difference is, as you said, that Byte is a wrapper class to byte. 正如你所说,区别在于Byte是一个字节的包装类。 As byte is a primitive, you cannot assing null to any byte variables. 由于byte是基元,因此不能将null赋给任何byte变量。 In contrast, Byte is an object, so you can assign null . 相反, Byte是一个对象,因此您可以指定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. 正如Vulcan所说,Byte被自动装箱到字节,这意味着如果JVM发现它可以使用字节而不是字节对象,它会用字节字符替换出现的字节。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM