我可以将 CharBuffer 转换为 IAppendableCharSequence
其实你不能。您只能将类的实例强制转换为该类有意实现的类型。CharBuffer 实现 Appendable 和 CharSequence 的事实并不意味着它实现了 IAppendableCharSequence 接口。
编译器允许强制转换,因为它无法判断CharBuffer.allocate(512)
. 据编译器所知,它可以返回一个明确实现 IAppendableCharSequence 的 CharBuffer 子类。但如果对象没有真正实现该接口,则强制转换将在运行时抛出 ClassCastException。
然而,new StringBuilder(512)
保证新对象是 StringBuilder 而不是它的子类,因此编译器可以在编译时看到强制转换不起作用。
您的问题的一种解决方案是制作一个实现您的接口的通用包装器:
public static <T extends CharSequence & Appendable> IAppendableCharSequence wrap(T t) {
if (t == null) throw new NullPointerException();
final CharSequence csq = t;
final Appendable a = t;
return new IAppendableCharSequence() {
@Override
public int length() {
return csq.length();
}
@Override
public char charAt(int index) {
return csq.charAt(index);
}
@Override
public CharSequence subSequence(int start, int end) {
return csq.subSequence(start, end);
}
@Override
public Appendable append(CharSequence s) throws IOException {
a.append(s);
return this;
}
@Override
public Appendable append(CharSequence s, int start, int end) throws IOException {
a.append(s, start, end);
return this;
}
@Override
public Appendable append(char c) throws IOException {
a.append(c);
return this;
}
};
}
(声明的csq
和a
变量在此处并不是绝对必要的,因为可以t
直接调用相同的方法,但是额外的变量通过避免每次调用其方法之一时都需要进行强制转换,从而使返回的 IAppendableCharSequence 对象更快一些。声明这些变量还会进行早期安全检查,即调用者没有绕过泛型,否则只有在尝试使用返回的 IAppendableCharSequence 时才会导致失败。)
一旦你有了这个方法,你就可以做到这两个:
m_buffer = wrap(CharBuffer.allocate(512));
m_buffer = wrap(new StringBuilder(512));
你也可以用其他实现 CharSequence 和 Appendable 的东西来调用它。