Skip to content

I can’t understand casting interface to children that don’t have any parents

I am studying lambda and then WebClient Class so I am creating bean of WebClient

ExchangeStrategies exchangeStrategies = ExchangeStrategies.builder().build();
    
exchangeStrategies.messageWriters() 
                      .stream()
                      .filter(LoggingCodecSupport.class::isInstance)
                      .forEach(writer -> ((LoggingCodecSupport)writer).setEnableLoggingRequestDetails(true));

I think top codes and bottom codes are the same

    ExchangeStrategies exchangeStrategies = ExchangeStrategies.builder().build();
    
    exchangeStrategies.messageWriters()
                      .stream()
                      .filter(new Predicate<HttpMessageWriter>() {
                          public boolean test(HttpMessageWriter t) {
                              return LoggingCodecSupport.class.isInstance(t);
                          };
                      })
                      .forEach(new Consumer<HttpMessageWriter>() {
                            public void accept(HttpMessageWriter t) {
                                ((LoggingCodecSupport)t).setEnableLoggingRequestDetails(true);
                            };
                      }); 

I don’t understand this cast situation because HttpMessageWriter is interface and LoggingCodecSupport is class but LoggingCodecSupport doesn’t implement HttpMessageWriter, so I think HttpMessageWriter can’t cast to LoggingCodecSupport

.forEach(new Consumer<HttpMessageWriter>() {
        public void accept(HttpMessageWriter t) {
                ((LoggingCodecSupport)t).setEnableLoggingRequestDetails(true);
        };
}); 

This is the code of HttpMessageWriter

public interface HttpMessageWriter<T> {
         ....
}

This is the code of LoggingCodecSupport

public class LoggingCodecSupport {
            ....
}

I tried to test this situation but it makes java.lang.ClassCastException

public class Test4 {
   public static void main(String[] args) {
      Parent parent = new Parent() {};
      ((Child)parent).foo();
    
   }
}

class Child{
   public void foo() {
      System.out.println("foo");
   }
}

interface Parent{

}

Help me to understand this thing

and make this code but it makes java.lang.ClassCastException,too

public class Test4 {
    public static void main(String[] args) {
        Parent parent = new Parent() {};
        ((Child)parent).foo();
    
    }
}

class Child{
    public void foo() {
        System.out.println("foo");
    }
}

interface Parent{

}

class bar extends Child implements Parent{

}

Answer

Assuming you are using the latest Spring, this is because one of the subclasses from LoggingCodecSupport implements the HttpMessageWriter interface.

You can take a look at this class FormHttpMessageWriter

It extends LoggingCodecSupport but implements a HttpMessageWriter interface. That’s why it can be cast without throwing an exception.

The example should be like this

public class Test4 {
  public static void main(String[] args) {
    Parent bar = new Bar() {};
    ((Child)bar).foo();
  }
}

class Child {
  public void foo() {
    System.out.println("foo");
  }
}

interface Parent {

}

class Bar extends Child implements Parent {

}

we can assume HttpMessageWriter is the Parent interface, the LoggingCodecSupport is the Child class, and the FormHttpMessageWriter is the Bar class.