java - 为什么注册到 DatagramChannel 的 SelectionKey 在 Scala 中返回 SelectableChannel 而不是 Java?

标签 java scala nio casting

我正在转换一些 Java NIO 代码以在 Scala 中运行,但收到​​错误,因为我调用的 SelectionKey 返回 SelectableChannel 而不是 DatagramChannel,DatagramChannel 是 SelectableChannel 的子类,也是我在代码的开头。我不是从Java转到Scala的,所以我对Java的了解其实很有限。在我看来,Java 代码 DatagramChannel channel = (DatagramChannel) key.channel(); 将 channel 类型转换为 DatagramChannel。这是我需要在 Scala 代码中执行的操作吗?

Scala 代码:

val channel = DatagramChannel.open()
val selector = Selector.open()
println("Attempting to bind to socket " + port)
channel.socket().bind(new InetSocketAddress(port))
println("Bound to socket " + port)
channel.configureBlocking(isBlocking)
println("Attempting to registered selector")
channel.register(selector, SelectionKey.OP_READ)
println("Registered selector")

println("Ready to receive data!");
while (true) {
  try {
    while(selector.select() > 0) {
      val keyIterator = selector.selectedKeys().iterator();
      while (keyIterator.hasNext()) {
        val key = keyIterator.next();
        if (key.isReadable()) {
          val channel = key.channel(); // FIXME: returning a SelectableChannel instead of a DatgramChannel
          var buffer: Array[Byte] = Array();
          val byteBuffer = ByteBuffer.wrap(buffer);
          val sockAddress = channel.receive(byteBuffer);
// ...

原始Java代码:

channel = DatagramChannel.open();
selector = Selector.open();
System.out.println("Attempting to bind to socket " + port);
channel.socket().bind(new InetSocketAddress(port));
System.out.println("Bound to socket " + port);
channel.configureBlocking(isBlocking);
System.out.println("Attempting to registered selector");
channel.register(selector, SelectionKey.OP_READ);
System.out.println("Registered selector");
System.out.println("Ready to receive data!");
while (true) {
  try {
    while(selector.select() > 0) {
      Iterator keyIterator = selector.selectedKeys().iterator();
      while (keyIterator.hasNext()) {
        SelectionKey key = (SelectionKey) keyIterator.next();
        if (key.isReadable()) {
          DatagramChannel channel = (DatagramChannel) key.channel();
          byte[] buffer = new byte[2048];
          ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);
          SocketAddress sockAddress = channel.receive(byteBuffer);
// ...

最佳答案

SelectionKey.channel()总是返回 SelectableChannel 。此时分配的 channel 类型并不真正相关,因此您必须对其进行强制转换。

关于java - 为什么注册到 DatagramChannel 的 SelectionKey 在 Scala 中返回 SelectableChannel 而不是 Java?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2135525/

相关文章:

从 Google Cloud Storage 下载时的 Java NIO 阻塞/非阻塞问题

scala - 由 : java. lang.ClassNotFoundException : org. apache.hadoop.hbase.HBaseConfiguration 引起

scala - 我可以为 == 重现 Scala 的行为吗?

scala - 检查 2 个集合是否包含在 Scala 中

java - 将 Java NIO 用于流水线 Http

java - 检查并返回 boolean 值

java - 从 Android Activity 调用时 OpenCv 崩溃

java - 二进制 SVM 中的错误分类

java - 在 Java 中使用 SimpleDateFormat 日期

Java NIO : how to protect global data effectively?