Java 将字节写入文件时出现IllegalArgumentException

Java 将字节写入文件时出现IllegalArgumentException,java,clojure,io,byte,Java,Clojure,Io,Byte,use-output-stream-1按预期工作,并且已验证写入的文件。我不理解通过use-output-stream-2抛出错误 (ns huffman.core (:use [clojure.java.io :only [output-stream]])) (defn use-output-stream-1 [] (with-open [o (output-stream path)] (.write o (unchecked-byte 255)) (.write o

use-output-stream-1
按预期工作,并且已验证写入的文件。我不理解通过
use-output-stream-2
抛出错误

(ns huffman.core
  (:use [clojure.java.io :only [output-stream]]))

(defn use-output-stream-1 []
  (with-open [o (output-stream path)]
    (.write o (unchecked-byte 255))
    (.write o (unchecked-byte (Integer/parseInt "01010101" 2)))
    ))

(defn rb [b]
  (unchecked-byte (Integer/parseInt b 2)))

(defn use-output-stream-2 []
  (with-open [o (output-stream path)]
    (.write o (unchecked-byte 255))
    (.write o (rb "01010101"))
    ))
编辑。我假设这与评估顺序有关,所以我写了一个宏

huffman.core> (use-output-stream-1)
nil
huffman.core> (rb "01010101")
85
huffman.core> (use-output-stream-2)
IllegalArgumentException No matching method found: write for class java.io.BufferedOutputStream  clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:80)
huffman.core> 

这似乎解决了问题,但我想了解发生了什么。我不明白为什么不先计算
(rb“01010101”)
,然后将结果传递给
。write

缓冲输出流。write
需要一个int(即使它只写入一个字节)。Clojure的类型强制系统将未装箱字节(如由特殊函数(如
unchecked byte
)返回的字节)强制为int(),但不强制装箱字节(如由用户定义函数返回的字节)。您可以在将参数传递给写操作之前重新取消绑定:
(.write o(byte)(rb“01010101”))
应该可以工作。使用类型提示也会有类似的帮助:
(.write o^ byte(rb“01010101”)
,或
(.write o^int(rb“01010101”)
将产生相同的结果。@alepher,您能将粘贴复制到答案中吗(如果您想要一些互联网点)如果没有,那么我就删除帖子。只是想检查一下:用户定义的函数总是返回装箱类型?我的理解是肯定的;唯一的例外是你可以给函数一个
^long
^double
类型提示,以避免装箱一个数字返回值,并有更快的算法。如果有更多的人如果我错过了一些边缘案例,经验丰富的人可以发表评论。
(defmacro rb-macro [b]
  `(unchecked-byte (Integer/parseInt ~b 2)))

(defn use-output-stream-3 []
  (with-open [o (output-stream path)]
    (.write o (unchecked-byte 255))
    (.write o (rb-macro "01010101"))
    ))