The substituability test is breaking the encapsulation

Remi Forax forax at
Mon Feb 25 10:11:28 UTC 2019

Hi all,
there is another issue with making the component wide test available for any value types, it's leaking the implementation.

Let say we have this class:

public value class GuessANumber {
  private final int value;
  public GuessANumber(int value) {
    this.value = value;
  public enum Response { LOWER, GREATER, FOUND };
  public Response guess(int guess) {
    if (value < guess) {
      return Response.LOWER;
    if (value > guess) {
      return Response.GREATER;
    return Response.FOUND;
  public static GuessANumber random(int seed) {
    return new GuessANumber(new Random(seed).nextInt(1024));

you can naively think that if we have an an instance of GuessANumber
  var number = GuessANumber.random(0);
you have can not get the value of the private field of that instance,
but using == you can find it because you can use == to test if number is substituable to a user created GuessANumber.

here is how to find the value without using the method guess()
  System.out.println(IntStream.range(0, 1024).filter(n -> new GuessANumber(n) == number).findFirst());


More information about the valhalla-spec-observers mailing list