blob: 80ac6353c1395782fc8b6a62c90ab872e1549698 [file] [log] [blame]
/*
* Copyright (c) 2016 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
package org.mockito.internal.util;
import org.mockito.internal.creation.instance.InstantiationException;
import java.lang.reflect.Method;
/**
* Helper class to work with features that were introduced in Java versions after 1.5.
* This class uses reflection in most places to avoid coupling with a newer JDK.
*/
public final class JavaEightUtil {
// No need for volatile, these optionals are already safe singletons.
private static Object emptyOptional;
private static Object emptyOptionalDouble;
private static Object emptyOptionalInt;
private static Object emptyOptionalLong;
private JavaEightUtil() {
// utility class
}
/**
* Creates an empty Optional using reflection to stay backwards-compatible with older JDKs.
*
* @return an empty Optional.
*/
public static Object emptyOptional() {
// no need for double-checked locking
if (emptyOptional != null) {
return emptyOptional;
}
return emptyOptional = invokeNullaryFactoryMethod("java.util.Optional", "empty");
}
/**
* Creates an empty OptionalDouble using reflection to stay backwards-compatible with older JDKs.
*
* @return an empty OptionalDouble.
*/
public static Object emptyOptionalDouble() {
// no need for double-checked locking
if (emptyOptionalDouble != null) {
return emptyOptionalDouble;
}
return emptyOptionalDouble = invokeNullaryFactoryMethod("java.util.OptionalDouble", "empty");
}
/**
* Creates an empty OptionalInt using reflection to stay backwards-compatible with older JDKs.
*
* @return an empty OptionalInt.
*/
public static Object emptyOptionalInt() {
// no need for double-checked locking
if (emptyOptionalInt != null) {
return emptyOptionalInt;
}
return emptyOptionalInt = invokeNullaryFactoryMethod("java.util.OptionalInt", "empty");
}
/**
* Creates an empty OptionalLong using reflection to stay backwards-compatible with older JDKs.
*
* @return an empty OptionalLong.
*/
public static Object emptyOptionalLong() {
// no need for double-checked locking
if (emptyOptionalLong != null) {
return emptyOptionalLong;
}
return emptyOptionalLong = invokeNullaryFactoryMethod("java.util.OptionalLong", "empty");
}
/**
* Creates an empty Stream using reflection to stay backwards-compatible with older JDKs.
*
* @return an empty Stream.
*/
public static Object emptyStream() {
// note: the empty stream can not be stored as a singleton.
return invokeNullaryFactoryMethod("java.util.stream.Stream", "empty");
}
/**
* Creates an empty DoubleStream using reflection to stay backwards-compatible with older JDKs.
*
* @return an empty DoubleStream.
*/
public static Object emptyDoubleStream() {
// note: the empty stream can not be stored as a singleton.
return invokeNullaryFactoryMethod("java.util.stream.DoubleStream", "empty");
}
/**
* Creates an empty IntStream using reflection to stay backwards-compatible with older JDKs.
*
* @return an empty IntStream.
*/
public static Object emptyIntStream() {
// note: the empty stream can not be stored as a singleton.
return invokeNullaryFactoryMethod("java.util.stream.IntStream", "empty");
}
/**
* Creates an empty LongStream using reflection to stay backwards-compatible with older JDKs.
*
* @return an empty LongStream.
*/
public static Object emptyLongStream() {
// note: the empty stream can not be stored as a singleton.
return invokeNullaryFactoryMethod("java.util.stream.LongStream", "empty");
}
/**
* Invokes a nullary static factory method using reflection to stay backwards-compatible with older JDKs.
*
* @param fqcn The fully qualified class name of the type to be produced.
* @param methodName The name of the factory method.
* @return the object produced.
*/
private static Object invokeNullaryFactoryMethod(final String fqcn, final String methodName) {
try {
final Class<?> type = Class.forName(fqcn);
final Method method = type.getMethod(methodName);
return method.invoke(null);
// any exception is really unexpected since the type name has
// already been verified
} catch (final Exception e) {
throw new InstantiationException(
String.format("Could not create %s#%s(): %s", fqcn, methodName, e), e);
}
}
}