I created a class GenericFunction that implements Function and BiFunction. But it cannot be compiled.
public class GenericFunction<T, U, R> implements
Function<T, R>, BiFunction<T, U, R> {
#Override
public R apply(T t, U u) {
return null;
}
#Override
public R apply(T t) {
return null;
}
}
The error message is:
src\obscure\test\GenericFunction.java:6: error:
types BiFunction<T,U,R> and Function<T,R> are incompatible;
both define andThen(java.util.function.Function<? super R,? extends V>),
but with unrelated return types
public class GenericFunction<T, U, R> implements
^
where T,U,R are type-variables:
T extends Object declared in class GenericFunction
U extends Object declared in class GenericFunction
R extends Object declared in class GenericFunction
1 error
How can I do that?
I have no idea why you would want something like this, but it seemed like an interesting challenge...
The main problem is that both Function & BiFunction implement a default andThen function, both having the exact same signature, so your class doesn't know which to call. You just have to provide your own implementation, then its not ambiguous anymore. However the implementation is tricky.
The java docs say the method:
Returns a composed function that first applies this function to its input, and then applies the after function to the result.
... so that means returning a new GenericFunction, where both apply methods are now compositions.
I give you this monstrosity:
public class GenericFunction<T, U, R> implements Function<T, R>, BiFunction<T, U, R> {
#Override
public R apply(T t, U u) {
return null;
}
#Override
public R apply(T t) {
return null;
}
#Override
public <V> GenericFunction<T, U, V> andThen(Function<? super R, ? extends V> after) {
return new GenericFunctionAndThen<>(after);
}
private class GenericFunctionAndThen<V> extends GenericFunction<T, U, V> {
private final Function<? super R, ? extends V> after;
public GenericFunctionAndThen(Function<? super R, ? extends V> after) {
this.after = after;
}
#Override
public V apply(T t) {
return after.apply(GenericFunction.this.apply(t));
}
#Override
public V apply(T t, U u) {
return after.apply(GenericFunction.this.apply(t, u));
}
}
}
This uses the most obscure feature of Java that I know of... I don't even know the name! ClassName.this is used in a nested class to refer to a method (or field) in the enclosing instance, if the method is shadowed.
Extending from #romacafe's answer, one thing that I don't like about it is that GenericFunctionAndThen extends GenericFunction without reusing any of the behaviour of its super class – which looks to me as a bad smell.
Things will be cleaner if you implemented GenericFunction as an interface instead:
public interface GenericFunction<T, U, R> extends Function<T, R>, BiFunction<T, U, R> {
#Override
default <V> GenericFunction<T, U, V> andThen(Function<? super R, ? extends V> after) {
return new GenericFunction<T, U, V>() {
#Override
public V apply(final T t, final U u) {
return after.apply(GenericFunction.this.apply(t, u));
}
#Override
public V apply(final T t) {
return after.apply(GenericFunction.this.apply(t));
}
};
}
}
This way you have a simple implementation of the generic behaviour (the andThen method), and you can implement your specific behaviour (the 2 apply methods) in a specific class without relying on inheritance.
Related
I created a Java class to decorate another interface with generics. However, it always has some compiler errors. This is the tailored sample code that could reproduce the error.
public interface GenericInterface<T> {
<U, V> GenericInterface<V> testFunc(BiFunction<? super T, ? super U, ? extends V> biFunction);
}
class GenericClass<T> implements GenericInterface<T> {
private GenericInterface<T> delegate;
public GenericClass(GenericInterface<T> dele) {
this.delegate = dele;
}
#Override
public <U, V> GenericInterface<V> testFunc(BiFunction<? super T, ? super U, ? extends V> biFunction) {
GenericClass<T> impl = new GenericClass<T>(delegate);
return impl.testFunc((t, u) -> {
// Do something here ...
// ...
// Error for argument u: Required type: capture of ? super U, Provided: Object
return biFunction.apply(t, u);
});
}
}
I tried a whole week and could not figure out what's wrong with it. Actually, I am new to advanced Java generics.
Remember, ? is like a one-use new type variable.
Therefore, the ? super T in your argument's BiFunction generics, does not have to be the same type as the ? super T as required by the testFunc invocation.
This is fixable:
#Override
public <U, V> GenericInterface<V> testFunc(BiFunction<? super T, ? super U, ? extends V> biFunction) {
GenericClass<T> impl = new GenericClass<T>(delegate);
BiFunction<T, U, V> b = (t, u) -> {
// do something
return biFunction.apply(t, u);
};
return impl.testFunc(b);
}
I am working on an old java application that uses Java 1.7. I would like to make use of the java.util.function.Function interface. However, this is only supported in Java 1.8+.
So I would like to write my own implementation in Java 1.7.
import java.util.Objects;
public interface Function<T, R> {
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v)); // lambda expression
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t)); // lambda expression
}
static <T> Function<T, T> identity() {
return t -> t; // lambda expression
}
}
The above gives me compile errors on the lambda expressions.
Question
How do I write the above lambda expressions in Java 1.7?
Since you can't actually create an interface with default methods, I think your best chance are static methods.
public interface Function<T, R> {
R apply(T t);
public static <T, V, R> Function<V, R> compose(Function<? super V, ? extends T> before, Function<? super T, ? super R> after) {
return new CombiningFunction<T, V, R>(before, after);
}
public static <T, R, V> Function<T, V> andThen(Function<? super T, ? super R> before, Function<? super R, ? extends V> after) {
return new CombiningFunction<T, V, R>(before, after);
}
static <T> Function<T, T> identity() {
return new Function<T, T> {
T apply(T t) { return t; }
}
}
}
class CombiningFunction<T, V, R> implements Function<T, R> {
Function<T, V> first;
Function<V, R> second;
public R apply(T t) {
V intermediate = first.apply(t);
return second.apply(intermediate);
}
}
But like KarelG mentions in the comments, it's really not advisable to do this; not to mention that this isn't nearly as elegant as in Java 8; after all, functional interfaces are pretty much geared towards lambdas, and if you don't have them, all usage will be as awkward as the implementation above.
You can use IntellijIdea to change it automatically, There is a result of IntellijIdea:
import java.util.Objects;
public interface Function<T, R> {
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return new Function<V, R>() {
#Override
public R apply(V v) {
return Function.this.apply(before.apply(v));
}
}; // lambda expression
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
Function<T, V> tvFunction = new Function<T, V>() {
#Override
public V apply(T t) {
return after.apply(Function.this.apply(t));
}
};
return tvFunction; // lambda expression
}
static <T> Function<T, T> identity() {
return new Function<T, T>() {
#Override
public T apply(T t) {
return t;
}
}; // lambda expression
}
}
Problem
I am writing a Result type in Java, and I have found a need for it to have a method that performs an operation which may fail, and then encapulates the value or exception in a new Result object.
I had hoped this would work:
#FunctionalInterface
public interface ThrowingSupplier<R, E extends Throwable>
{
R get() throws E;
}
public class Result<E extends Throwable, V>
{
...
public static <E extends Throwable, V> Result<E, V> of(ThrowingSupplier<V, E> v)
{
try
{
return value(v.get());
}
catch(E e)
{
return error(e);
}
}
...
}
But Java cannot catch an exception defined by a type parameter.
I have also tried using instanceof, but that also cannot be used for generics. Is there any way I can implement this method?
Definitions
This is my result type before the addition of the of method. It's intended to be similar to both Haskell's Either and rust's Result, while also having a meaningful bind operation:
public class Result<E extends Throwable, V>
{
private Either<E, V> value;
private Result(Either<E, V> value)
{
this.value = value;
}
public <T> T match(Function<? super E, ? extends T> ef, Function<? super V, ? extends T> vf)
{
return value.match(ef, vf);
}
public void match(Consumer<? super E> ef, Consumer<? super V> vf)
{
value.match(ef, vf);
}
/**
* Mirror of haskell's Monadic (>>=)
*/
public <T> Result<E, T> bind(Function<? super V, Result<? extends E, ? extends T>> f)
{
return match(
(E e) -> cast(error(e)),
(V v) -> cast(f.apply(v))
);
}
/**
* Mirror of Haskell's Monadic (>>) or Applicative (*>)
*/
public <T> Result<E, T> then(Supplier<Result<? extends E, ? extends T>> f)
{
return bind((__) -> f.get());
}
/**
* Mirror of haskell's Applicative (<*)
*/
public Result<E, V> peek(Function<? super V, Result<? extends E, ?>> f)
{
return bind(v -> f.apply(v).then(() -> value(v)));
}
public <T> Result<E, T> map(Function<? super V, ? extends T> f)
{
return match(
(E e) -> error(e),
(V v) -> value(f.apply(v))
);
}
public static <E extends Throwable, V> Result<E, V> error(E e)
{
return new Result<>(Either.left(e));
}
public static <E extends Throwable, V> Result<E, V> value(V v)
{
return new Result<>(Either.right(v));
}
/**
* If the result is a value, return it.
* If it is an exception, throw it.
*
* #return the contained value
* #throws E the contained exception
*/
public V get() throws E
{
boolean has = match(
e -> false,
v -> true
);
if (has)
{
return value.fromRight(null);
}
else
{
throw value.fromLeft(null);
}
}
/**
* Upcast the Result's type parameters
*/
private static <E extends Throwable, V> Result<E, V> cast(Result<? extends E, ? extends V> r)
{
return r.match(
(E e) -> error(e),
(V v) -> value(v)
);
}
}
And the Either type, designed to closely mirror Haskell's Either:
/**
* A container for a disjunction of two possible types
* By convention, the Left constructor is used to hold an error value and the Right constructor is used to hold a correct value
* #param <L> The left alternative type
* #param <R> The right alternative type
*/
public abstract class Either<L, R>
{
public abstract <T> T match(Function<? super L, ? extends T> lf, Function<? super R, ? extends T> rf);
public abstract void match(Consumer<? super L> lf, Consumer<? super R> rf);
public <A, B> Either<A, B> bimap(Function<? super L, ? extends A> lf, Function<? super R, ? extends B> rf)
{
return match(
(L l) -> left(lf.apply(l)),
(R r) -> right(rf.apply(r))
);
}
public L fromLeft(L left)
{
return match(
(L l) -> l,
(R r) -> left
);
}
public R fromRight(R right)
{
return match(
(L l) -> right,
(R r) -> r
);
}
public static <L, R> Either<L, R> left(L value)
{
return new Left<>(value);
}
public static <L, R> Either<L, R> right(R value)
{
return new Right<>(value);
}
private static <L, R> Either<L, R> cast(Either<? extends L, ? extends R> either)
{
return either.match(
(L l) -> left(l),
(R r) -> right(r)
);
}
static class Left<L, R> extends Either<L, R>
{
final L value;
Left(L value)
{
this.value = value;
}
#Override
public <T> T match(Function<? super L, ? extends T> lf, Function<? super R, ? extends T> rf)
{
return lf.apply(value);
}
#Override
public void match(Consumer<? super L> lf, Consumer<? super R> rf)
{
lf.accept(value);
}
}
static class Right<L, R> extends Either<L, R>
{
final R value;
Right(R value)
{
this.value = value;
}
#Override
public <T> T match(Function<? super L, ? extends T> lf, Function<? super R, ? extends T> rf)
{
return rf.apply(value);
}
#Override
public void match(Consumer<? super L> lf, Consumer<? super R> rf)
{
rf.accept(value);
}
}
}
Example Usage
The main use of this is to convert exception-throwing operations into monadic ones. This allows for (checked) exception-throwing methods to be used in streams and other functional contexts, and also allows for pattern matching and binding on the return type.
private static void writeFiles(List<String> filenames, String content)
{
filenames.stream()
.map(
(String s) -> Result.of(
() -> new FileWriter(s) //Open file for writing
).peek(
(FileWriter f) -> Result.of(
() -> f.write(content) //Write file contents
)
).peek(
(FileWriter f) -> Result.of(
() -> f.close()) //Close file
)
).forEach(
r -> r.match(
(IOException e) -> System.out.println("exception writing to file: " + e), //Log exception
(FileWriter f) -> System.out.println("successfully written to file '" + f + "'") //Log success
)
);
}
Just use the optimistic assumption that the interface fulfills the contract, as ordinary Java code will always do (enforced by the compiler). If someone bypasses this exception-checking, it’s not your responsibility to fix that:
public static <E extends Exception, V> Result<E, V> of(ThrowingSupplier<V, E> v) {
try {
return value(v.get());
}
catch(RuntimeException|Error x) {
throw x; // unchecked throwables
}
catch(Exception ex) {
#SuppressWarnings("unchecked") E e = (E)ex;
return error(e);
}
}
Note that even the Java programming language agrees that it is okay to proceed with this assumption, e.g.
public static <E extends Exception, V> Result<E, V> of(ThrowingSupplier<V, E> v) throws E {
try {
return value(v.get());
}
catch(RuntimeException|Error x) {
throw x; // unchecked throwables
}
catch(Exception ex) {
throw ex; // can only be E
}
}
is valid Java code, as under normal circumstances, the get method can only throw E or unchecked throwables, so it is valid to rethrow ex here, when throws E has been declared. We only have to circumvent a deficiency of the Java language when we want to construct a Result parameterized with E.
You need access to the class of the exception and then use some generics in the catch block.
One simple way is to pass the Class<E> class to the Result.of method:
public static <E extends Throwable, V> Result<E, V> of(
ThrowingSupplier<V, E> v,
Class<E> errorType) {
try {
return value(v.get());
} catch(Throwable e) {
if (errorType.isInstance(e)) {
return error(errorType.cast(e));
}
throw new RuntimeException(e); // rethrow as runtime?
}
}
Usage:
Result.of(() -> new FileWriter(s), IOException.class)
Class.isInstance is the dynamic equivalent of the instanceof static operator, while Class.cast is the same as statically casting: (E) e, except that we don't get a warning from the compiler.
EDIT: You need to think what to do when the catched Throwable is not of the type of the exception you are expecting. I've wrapped it in a RuntimeException and have rethrown it. This allows to keep using a fluent style for your monad, but is not transparent any more, as now any exception is wrapped in an unchecked exception. Maybe you could add a 3rd argument to Result.of to handle this specific case...
Update: this seems not to work at all. I'm keeping it here for now because I've linked to is elsewhere, and because it uses a method provided in other accepted answers, which I would like to continue to investigate.
Using Federico's answer and the answer linked in the comment, I have deduced a solution with the same method signature as the original problem, and I have created a class which encapsulates this functionality for future use.
The Result implementation:
public class Result<E extends Exception, V>
{
...
public static <E extends Exception, V> Result<E, V> of(ThrowingSupplier<V, E> v)
{
try
{
return value(v.get());
}
catch(Exception e)
{
Class<E> errType = Reflector.getType();
if (errType.isInstance(e))
{
return error(errType.cast(e));
}
else
{
throw (RuntimeException) e;
}
}
}
...
}
And the Reflector:
import java.lang.reflect.ParameterizedType;
/**
* This class only exists to provide a generic superclass to {#link Reflector}
* #param <E> The type for the subclass to inspect
*/
abstract class Reflected<E>
{ }
/**
* This class provides the ability to obtain information about its generic type parameter.
* #param <E> The type to inspect
* #author
*/
#Deprecated
public class Reflector<E> extends Reflected<E>
{
/**
* Returns the class corresponding to the type {#code <E>}.
* #param <E> The type to inspect
* #return The class corresponding to the type {#code <E>}
*/
public static <E> Class<E> getType()
{
return new Reflector<E>().getParameterType();
}
private Reflector() {}
private Class<E> getParameterType()
{
final ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
return (Class<E>) type.getActualTypeArguments()[0];
}
}
I have a custom interface I've been using for some time that looks something like this:
public interface Function<T, R> {
R call(T input);
}
I'd like to retrofit this interface with both Java's Function as well as Guava's Function, while keeping it a FunctionalInterface. I thought I had the perfect arrangement:
#FunctionalInterface
public interface Function<T, R> extends
java.util.function.Function<T, R>,
com.google.common.base.Function<T, R> {
R call(T input);
#Override
default R apply(T input) {
return call(input);
}
}
Both superinterfaces declare the same apply() method, which has been implemented in my interface, leaving only the abstract call() method. Strangely, it won't compile, telling me
Invalid '#FunctionalInterface' annotation; Function<T,R> is not a functional interface
Stranger still, the following variations compile just fine:
#FunctionalInterface
public interface Function<T, R> extends
java.util.function.Function<T, R> {
R call(T input);
#Override
default R apply(T input) {
return call(input);
}
}
#FunctionalInterface
public interface Function<T, R> extends
com.google.common.base.Function<T, R> {
R call(T input);
#Override
default R apply(T input) {
return call(input);
}
}
public interface Function<T, R> extends
java.util.function.Function<T, R>,
com.google.common.base.Function<T, R> {
R call(T input);
#Override
default R apply(T input) {
return call(input);
}
}
#FunctionalInterface
public interface Function<T, R> extends
java.util.function.Function<T, R>,
com.google.common.base.Function<T, R> {
#Override
R apply(T input);
}
Is there a reason the first version won't compile?
As stated in the comments, it compiles fine with the oracle compiler.
It is an eclipse bug.
Awaiting for a bug fix, personally i will remove the annotation #FunctionalInterface (your 3rd variation):
public interface Function<T, R>
extends
java.util.function.Function<T, R>,
com.google.common.base.Function<T, R> {
R call(T input);
#Override
default R apply(T input) {
return call(input);
}
}
The major inconvenient of this solution is that the eclipse compiler bug prevent from using the Function as a lambda target type.
If you really want to keep #FunctionalInterface on your Function, a (ugly) workaround might be to introduce an intermediate interface:
public interface AdapterFunction<T, R>
extends
java.util.function.Function<T, R>,
com.google.common.base.Function<T, R> {
#Override
default R apply(T input) {
return null;
}
}
and let your Function extends this AdapterFunction:
#FunctionalInterface
public interface Function<T, R>
extends
AdapterFunction<T, R> {
R call(T input);
#Override
default R apply(T input) {
return call(input);
}
}
In this case, the Function is a valid target type for eclipse too:
Function<String, Object> function = st -> st.toString();
I have the following code snippet (it is just example):
public class Class123 extends Thread implements Serializable, Runnable {
public <T extends String> T callFriend(String name, Class<T> type) {
return "";
}
}
Is it possible to get <T extends String> T?
method.getGenericReturnType() == "T"
method.getReturnType().getName() == "java.lang.String"
My second example is:
public abstract class Function<T, R> {
public <V> Function<T, V> then(Function<? super R, ? extends V> after) {
return new Function<T, V>() {
#Override
public V apply(T t) {
return after.apply(Function.this.apply(t));
}
};
}
public abstract R apply(T t);
}
And I want to get: <V> Function<T, V>.
When you say you want this <V> Function<T, V>, then this is what you are looking for (I presume so because obviously the type gets erased)
Method andThen = Function.class.getDeclaredMethod("then", Function.class);
Type t = andThen.getGenericReturnType();
ParameterizedType claz= (ParameterizedType)t;
System.out.println(claz);
System.out.println(Arrays.asList(claz.getActualTypeArguments()));
It prints:
Function<T, V>
[T, V]
Similarly for your first case. Just as an example you can also do it for variables and not just methods:
class Outer{
//Aim is to capture the type of generic type below. i.e. String
List<String> ls = new ArrayList<String>();
}
Field field = Outer.class.getDeclaredField("ls");
ParameterizedType p = (ParameterizedType) field.getGenericType();
Class<?> claz = (Class<?>)p.getActualTypeArguments()[0];
System.out.println(claz);
// prints class java.lang.String
Also this is a class I wrote for myself, where it easier to capture the type of generic class. In case it helps