The first big thing is that Java, especially in the days of when checked exceptions were a really big thing and less so in modern Java, was really into a certain kind of inheritance and interface design that didn't play well with error states and focused on the happy path. It is very difficult to make Java-esque interfaces that play well with checked exceptions because they like to abstract across network calls, in-memory structures, filesystem operations, and other side effectful tasks that have very different exception structures. An interface might have a single `writeData` method that might be backed by alternatively a write into an in-memory dictionary, a filesystem key-value store, a stateless REST API, or a bidirectional WebSocket channel which all have wildly different exceptions that can occur.
The second thing is that because checked exceptions were not actual return values but rather had their own special channel, they often did not play well with other Java API decisions such as e.g. streams or anything with `Runnable` that involved essentially the equivalent of a higher-order function (a function that takes as an argument another function). If e.g. you had something you wanted to call in a `Stream.map` that threw a checked exception, you couldn't use it, even if you notated in the enclosing method that you were throwing a checked exception because there was no way of telling `Stream.map` "if the function being `map`ed throws an exception rethrow it" which arose because checked exceptions weren't actual return values and therefore couldn't be manipulated the same way. You could get around it, but would have to resort to some shenanigans that would need to be repeated every time this issue came up for another API.
On the other hand if this wasn't a checked exception but was directly a part o the return value of a function, it would be trivial to handle this through the usual generics that Java has. And that is what something like `Result` accomplishes.