提问人:cpliu338 提问时间:8/3/2023 最后编辑:Hendrikcpliu338 更新时间:8/4/2023 访问量:78
ClassCast创建 javax.sound.sampled.Clip 时抛出异常
ClassCastException thrown when creating a javax.sound.sampled.Clip
问:
我想在 Java Swing 应用程序中播放声音。我参考了 https://www.baeldung.com/java-play-sound 并像这样修改:
模块信息.java
module sound {
requires java.desktop;
}
源文件位于同一文件夹 [mydomain]/desktopproject/sound 中。有一个带有 JButton 的 Swing JFrame,当我按下按钮时,以下代码片段会一直运行,直到最后一行抛出 ClassCastException:
audioStream = AudioSystem.getAudioInputStream(new BufferedInputStream(
new FileInputStream(new File("/path-to-my.wav"))
));
AudioFormat audioFormat = audioStream.getFormat();
DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
Clip audioClip = (Clip) AudioSystem.getLine(info);
异常消息如下所示:
Exception in thread "AWT-EventQueue-0"
java.lang.ClassCastException: class com.sun.media.sound.DirectAudioDevice$DirectSDL
cannot be cast to class javax.sound.sampled.Clip
(com.sun.media.sound.DirectAudioDevice$DirectSDL
and javax.sound.sampled.Clip are in module java.desktop
of loader 'bootstrap')
我不确定问题出在哪里。我使用 openjdk 版本“11.0.20”2023-07-18,当我运行时,我得到:java --list-module
[email protected]
答:
根据文档(此处),您使用的构造函数的第一个参数是:DataLine.Info
Info 对象描述的数据行的类
然后,根据 's 方法的文档(这里):AudioSystem
getLine
获取与指定对象中的描述匹配的行。
Line.Info
此外,是一个 ,因此我认为 的文档也适用于 。我的假设主要来自OOP继承和对实现的信任。DataLine.Info
Line.Info
getLine
DataLine.Info
最后,错误是 ,它指示(并声明)返回的对象不是 的类型。ClassCastException
getLine
Clip
从文档和对错误的观察中,如果假设为真,并且在搜索类似的用法以获得灵感之后,人们可能会得出结论,构造函数的第一个参数应该是 返回的对象类型。这就是为什么我在问题的评论中建议尝试以下解决方案:DataLine.Info
getLine
更改以下代码行:
DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
自:
DataLine.Info info = new DataLine.Info(Clip.class, audioFormat);
为了获得 的实例 (这是 ,这是 )。Clip
DataLine
Line
我没有尝试过,我对包不是很熟悉(因此最初是一条评论),但是由于您报告它有效,我认为这是一个答案并写在这里。javax.sound.sampled
我不知道为什么人们仍然相信Baeldung的家伙是Java专家。他不是。
您可以只替换以下行:
AudioFormat audioFormat = audioStream.getFormat();
DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
Clip audioClip = (Clip) AudioSystem.getLine(info);
有了这个:
Clip audioClip = AudioSystem.getClip();
自 Java 1.5 以来,getClip() 方法就已经可用,因此 2023 年的一篇文章没有理由声称可以帮助 Java 程序员忽略它。
评论
audioFormat
AudioInputStream
Clip
评论
DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
DataLine.Info info = new DataLine.Info(Clip.class, audioFormat);