All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.fiolino.common.reflection.AlmostFinal Maven / Gradle / Ivy

Go to download

General structure to easily create dynamic logic via MethodHandles and others.

There is a newer version: 1.0.10
Show newest version
package org.fiolino.common.reflection;

import org.fiolino.common.util.Types;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MutableCallSite;

/**
 * Build a getter MethodHandle for some value that is nearly static final.
 * 

* It is meant for values that rather unlikely change, but have the option to do so. Unchanged values behave like * constants and are extremely fast, while changing the value may be very slow. *

* The getter handle will usually be held in a static final variable. The instance of this class is used * to update the value; it can be held anywhere. *

* You could also wrap the getter handle to a lambda function for easier use; however performance tests have shown * that this will result in a performance degradation that is at best comparable with access to direct non-final * static variables. Then it would be no use any more to not choose a modifiable static variable instead. *

* You can dismiss the instance of this class after handle creation if you don't need to change the value * any more. *

* Created by Kuli on 10/11/2016. */ public class AlmostFinal { private final Class type; private final MutableCallSite callSite; private AlmostFinal(Class type, Object initialValue) { this.type = type; callSite = new MutableCallSite(createGetterHandleFor(initialValue)); } private MethodHandle createGetterHandleFor(Object value) { return MethodHandles.constant(type, value); } /** * Creates the getter handle for this value. * * @return A handle of type ()<type> */ public MethodHandle createGetter() { return callSite.dynamicInvoker(); } /** * Gets the current value. If the original value is of a primitive type, then return its wrapper object. *

* While this method isn't really slow, it's not as fast as the getter method handle which is the preferred way * to get my value. */ @SuppressWarnings("unchecked") public T get() { try { return (T) callSite.getTarget().invoke(); } catch (RuntimeException | Error e) { throw e; } catch (Throwable t) { throw new AssertionError(t); } } /** * Updates to a new value. *

* Warning! This method may be slow. */ public void updateTo(T newValue) { T oldValue = get(); if (oldValue == newValue) { return; } callSite.setTarget(createGetterHandleFor(newValue)); MutableCallSite.syncAll(new MutableCallSite[] { callSite }); } /** * Creates a new instance for arbitrary Java objects. */ public static AlmostFinal forReference(Class type, T initialValue) { if (type.isPrimitive()) { throw new IllegalArgumentException(type.getName() + " not supported, please use a dedicated factory method!"); } return new AlmostFinal(type, initialValue); } /** * Creates a new instance for int constants. */ public static AlmostFinal forInt(int initialValue) { return new AlmostFinal<>(int.class, initialValue); } /** * Creates a new instance for long constants. */ public static AlmostFinal forLong(long initialValue) { return new AlmostFinal<>(long.class, initialValue); } /** * Creates a new instance for short constants. */ public static AlmostFinal forShort(short initialValue) { return new AlmostFinal<>(short.class, initialValue); } /** * Creates a new instance for byte constants. */ public static AlmostFinal forByte(byte initialValue) { return new AlmostFinal<>(byte.class, initialValue); } /** * Creates a new instance for float constants. */ public static AlmostFinal forFloat(float initialValue) { return new AlmostFinal<>(float.class, initialValue); } /** * Creates a new instance for double constants. */ public static AlmostFinal forDouble(double initialValue) { return new AlmostFinal<>(double.class, initialValue); } /** * Creates a new instance for char constants. */ public static AlmostFinal forChar(char initialValue) { return new AlmostFinal<>(char.class, initialValue); } /** * Creates a new instance for boolean constants. */ public static AlmostFinal forBoolean(boolean initialValue) { return new AlmostFinal<>(boolean.class, initialValue); } /** * Creates a new instance for any primitive type. */ public static AlmostFinal forPrimitive(Class wrapperType, T initialValue) { Class primType = Types.asPrimitive(wrapperType); if (primType == null) { throw new IllegalArgumentException(wrapperType.getName() + " is not a primitive wrapper!"); } return new AlmostFinal<>(primType, initialValue); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy