Java 重复剪辑
Java duplicate clip
我发现很多主题都在建议和讨论克隆,但我一直无法真正实现可以复制我的 Clip 对象的方法。
这是我尝试过的:
// ... setting up class ...
MyClip GunClip = new MyClip();
GunClip.set(AudioSystem.getClip());
AudioInputStream inputStream = AudioSystem.getAudioInputStream(new BufferedInputStream(getClass().getResourceAsStream("/Resources/sound/Laser.wav")));
GunClip.dummy.open(inputStream);
// ...
然后当一个事件被触发时,我想重复播放那个声音。所以我尝试复制它:
class MyClip implements Cloneable {
Clip dummy;
public MyClip() {
}
public Clip get() {
return dummy;
}
public void set(Clip c) {
this.dummy = c;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
我按照 this 主题中的建议实现了 Cloneable class。
然后我在播放之前克隆它:
MyClip c = (MyClip) GunClip.clone();
c.dummy.setFramePosition(0);
c.dummy.start();
但现在还是不行...
编辑:我已经弄清楚为什么它不起作用,这是因为它不是深度克隆并且原始 GunClip 使用的 InputStream 没有被克隆。但由于 Clip 是一个抽象接口,因此克隆它可能比正常情况下更难。
class MyClip implements Cloneable {
Clip dummy;
public MyClip() {
}
public Clip get() {
return dummy;
}
public void set(Clip c) {
this.dummy = c;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
如果你这样写代码,你基本上就是在说"The Object class knows everything about my custom class, including how to build it"。当然不是这样。
您需要根据需要调整克隆方法:
class MyClip implements Cloneable {
Clip dummy;
public MyClip() {
}
public Clip get() {
return dummy;
}
public void set(Clip c) {
this.dummy = c;
}
@Override
protected Object clone() throws CloneNotSupportedException {
MyClip clone = new MyClip(); // create a new instance of your class
clone.set(this.dummy); // make sure it has the same value for 'dummy'
// I would suggest improvement on your setter and getter name, though
return clone; // This returns an instance of MyClip, which has the exact same
// state as your current, but is a clone, and not the same instance.
}
}
为了调用它,您需要这样的东西:
public void getClone(MyClip original) {
MyClip Clone = (MyClip)original.clone();
}
编辑:
根据您的问题,原件的 'dummy' 也被感染,如果您想防止这种情况,只需让您的 Clip
class 也实施 Cloneable
,然后将您的将方法克隆到此:
@Override
protected Object clone() throws CloneNotSupportedException {
MyClip clone = new MyClip();
clone.set(this.dummy == null ? null : this.dummy.clone());
return clone;
}
我喜欢在我的对象中写一个复制构造函数。这为我提供了一种无需转换结果即可克隆对象的方法。您可以使用该构造函数以干净的方式实现 Cloneable,因此您的对象仍然支持该接口。这就是我的意思,包括以这两种方式克隆对象的示例代码:
static class MyClip implements Cloneable {
Clip dummy;
public MyClip() {
}
public MyClip(MyClip toCopy) {
dummy = toCopy.dummy;
}
public Clip get() {
return dummy;
}
public void set(Clip c) {
this.dummy = c;
}
@Override
public Object clone() {
return new MyClip(this);
}
}
public static void main(String... args) {
MyClip original = new MyClip();
MyClip clone1 = (MyClip)original.clone();
MyClip clone2 = new MyClip(original);
}
编写复制构造函数来复制对象的另一个好处是,有一种自然的方法可以让您的 superclass 参与复制操作,首先使用 'super(toCopy);' 调用它的复制构造函数, 然后复制你自己的 subclass 中的字段。这在此处不适用,因为您正在实现一个接口,但如果您要扩展另一个接口则很重要 class.
我发现很多主题都在建议和讨论克隆,但我一直无法真正实现可以复制我的 Clip 对象的方法。
这是我尝试过的:
// ... setting up class ...
MyClip GunClip = new MyClip();
GunClip.set(AudioSystem.getClip());
AudioInputStream inputStream = AudioSystem.getAudioInputStream(new BufferedInputStream(getClass().getResourceAsStream("/Resources/sound/Laser.wav")));
GunClip.dummy.open(inputStream);
// ...
然后当一个事件被触发时,我想重复播放那个声音。所以我尝试复制它:
class MyClip implements Cloneable {
Clip dummy;
public MyClip() {
}
public Clip get() {
return dummy;
}
public void set(Clip c) {
this.dummy = c;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
我按照 this 主题中的建议实现了 Cloneable class。
然后我在播放之前克隆它:
MyClip c = (MyClip) GunClip.clone();
c.dummy.setFramePosition(0);
c.dummy.start();
但现在还是不行...
编辑:我已经弄清楚为什么它不起作用,这是因为它不是深度克隆并且原始 GunClip 使用的 InputStream 没有被克隆。但由于 Clip 是一个抽象接口,因此克隆它可能比正常情况下更难。
class MyClip implements Cloneable {
Clip dummy;
public MyClip() {
}
public Clip get() {
return dummy;
}
public void set(Clip c) {
this.dummy = c;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
如果你这样写代码,你基本上就是在说"The Object class knows everything about my custom class, including how to build it"。当然不是这样。
您需要根据需要调整克隆方法:
class MyClip implements Cloneable {
Clip dummy;
public MyClip() {
}
public Clip get() {
return dummy;
}
public void set(Clip c) {
this.dummy = c;
}
@Override
protected Object clone() throws CloneNotSupportedException {
MyClip clone = new MyClip(); // create a new instance of your class
clone.set(this.dummy); // make sure it has the same value for 'dummy'
// I would suggest improvement on your setter and getter name, though
return clone; // This returns an instance of MyClip, which has the exact same
// state as your current, but is a clone, and not the same instance.
}
}
为了调用它,您需要这样的东西:
public void getClone(MyClip original) {
MyClip Clone = (MyClip)original.clone();
}
编辑:
根据您的问题,原件的 'dummy' 也被感染,如果您想防止这种情况,只需让您的 Clip
class 也实施 Cloneable
,然后将您的将方法克隆到此:
@Override
protected Object clone() throws CloneNotSupportedException {
MyClip clone = new MyClip();
clone.set(this.dummy == null ? null : this.dummy.clone());
return clone;
}
我喜欢在我的对象中写一个复制构造函数。这为我提供了一种无需转换结果即可克隆对象的方法。您可以使用该构造函数以干净的方式实现 Cloneable,因此您的对象仍然支持该接口。这就是我的意思,包括以这两种方式克隆对象的示例代码:
static class MyClip implements Cloneable {
Clip dummy;
public MyClip() {
}
public MyClip(MyClip toCopy) {
dummy = toCopy.dummy;
}
public Clip get() {
return dummy;
}
public void set(Clip c) {
this.dummy = c;
}
@Override
public Object clone() {
return new MyClip(this);
}
}
public static void main(String... args) {
MyClip original = new MyClip();
MyClip clone1 = (MyClip)original.clone();
MyClip clone2 = new MyClip(original);
}
编写复制构造函数来复制对象的另一个好处是,有一种自然的方法可以让您的 superclass 参与复制操作,首先使用 'super(toCopy);' 调用它的复制构造函数, 然后复制你自己的 subclass 中的字段。这在此处不适用,因为您正在实现一个接口,但如果您要扩展另一个接口则很重要 class.