Java 为什么使用打印流打印字节(数字数据类型)会给我字符?

Java 为什么使用打印流打印字节(数字数据类型)会给我字符?,java,arrays,byte,Java,Arrays,Byte,为什么编译下面的代码会产生ASCII代码值:GHI?我认为字节是一种数字数据类型?见下面的代码: import java.io.*; public class PrintStreamDemo { public static void main(String[] args) { byte c[] = {70, 71, 72, 73, 74, 75, 76}; // create printstream object PrintStream p

为什么编译下面的代码会产生ASCII代码值:GHI?我认为字节是一种数字数据类型?见下面的代码:

import java.io.*;

public class PrintStreamDemo {

   public static void main(String[] args) {
    
      byte c[] = {70, 71, 72, 73, 74, 75, 76};
      // create printstream object
      PrintStream ps = new PrintStream(System.out);
    
      // write bytes 1-3
      ps.write(c, 1, 3);
    
      // flush the stream
      ps.flush();
  }
}
我认为字节是一种数字数据类型

就数据类型而言,
byte
确实是一种数字数据类型,
char

Java编程语言的类型分为两类:基本类型和引用类型。基本类型(§4.2)为
布尔型和数值型。数字类型是整数类型
byte
short
int
long
char
,浮点类型是
float
double

char
表示字符”的含义是一个有用的抽象,它的范围恰好是UTF-16字符的范围。但是对计算机来说,
char
只有16个1和0,
byte
只有8个1和0。如何解释它们取决于口译员

当您使用
System.out.println()
打印
字节时,字节首先转换为
int
,该方法将它们解释为数字1,这就是
System.out.println(70b)
打印“70”而不是G的原因

另一方面,运行此程序的控制台将接收到的字节解释为UTF-8编码的字符串
System.out
,您的
ps
连接到它,
将字节写入控制台。这就是为什么70打印为“G”等



1如果您查看
println
实际执行的操作的源代码,您将看到在最低级别,它还调用
write(byte[],int,int)
,只是不写入字节70。相反,它写入字节55和48,这表示字符“7”和“0”。

首先,
System.out
已经是一个
PrintStream
。因此,将其包装在另一个
PrintStream
中是毫无意义的

其次,
print
write
在Java中不是一回事。甚至在
打印流上也没有

第三,尽管在Java中,
byte
是一种数字类型,
char
也是。因此,任何关于“它是一个数字,所以它必须打印为一个数字”的推理在Java中都不成立。相反,您需要查看API规范的详细信息


这里实际发生的是
PrintStream.write(byte[],int,int)
将字节从数组写入底层
OutputStream
,而不进行任何格式化或字符集编码,如此方法的中所述

在许多字符集编码中,字节值70、71和72对字符G、H和I进行编码(代码70、71和72以ASCII表示这些字母,许多编码“借用”了前128个代码的ASCII编码)

现在,可以推测,JVM使用的默认字符集编码是上面的一种。。。因此,您可以在控制台上看到“GHI”作为输出

然而。。。并不是所有的字符编码都是这样的。例如,如果您的平台的默认编码设置为16位编码,则字节
70
71
实际上将表示单个Unicode码点U+4647。。。这是一个汉字


如果您使用
ps.write(c[i])
ps.print(c[i])
替代,您将获得相同的行为。这将分别调用
PrintStream.write(int)
PrintStream.print(char)
。两者最终都将字节视为字符1的表示形式

如果要使用
PrintStream
打印格式化为数字的字节,则需要将其转换为
int

  ps.print((int) c[1]);
PrintStream.print(int)
方法打印其参数的十进制表示形式



1-以不同的方式
PrintStream.write(int)
只写入字节,而不考虑编码<代码>打印流。打印(字符)
应用正确的编码。根据打印的字节和字符编码,这两个调用可能会给出不同的结果。

字节和字符是数字数据类型,这并不意味着它们类似于int或float。。。字节以字节格式存储数据

要从字节数组读取数据,请使用ByteArrayInputStream

import java.io.*;

public class PrintStreamDemo {

   public static void main(String[] args) {
    
      byte c[] = {70, 71, 72, 73, 74, 75, 76};

      // Create the new byte array input stream  
      ByteArrayInputStream byt = new ByteArrayInputStream(buf);  
    
      // Print data
      int k = 0;  
      while ((k = byt.read()) != -1) {  
         //Conversion of a byte into character  
         char ch = (char) k;  
         System.out.println("ASCII value of Character is:" + k + "; Special character is: " + ch);  
      }  
      
      // flush the stream
      byt.flush();
  }
}

通过PrintStream发送字节,可以将它们打印为ASCII字符。71是G,72是H,73是I。您必须使用ByteArrayInputStream来读取字节内容。@Shambubu,如果您认为答案有帮助,请投票。。。