Getter für MutableLiveData

30 views
Skip to first unread message

Dennis

unread,
Aug 19, 2021, 1:30:33 PM8/19/21
to Project Lombok
MutableLiveData is used a lot (at least in Android development). Each time we expose this we need to write a Getter which only Exposes the super class LiveData. Because we do not want mutability outside our class. 

So for 

MutableLiveData<Boolean> simpleBoolean = new MutableLIveData<>(true);

we need a getter like this:

LiveData<Boolean> getSimpleBoolean(){ return simpleBoolean;);

We cannot use @Getter as this would expose MutableLiveData instead of LiveData. 

Wouldn't it be nice to include this feature into Lombok to get rid of these immense boiler plate code?

Chris Becker

unread,
Aug 20, 2021, 11:01:45 AM8/20/21
to project...@googlegroups.com
My first thought was that this is a really bad idea. Too restricted to the needs of Android devs.
My second thought was: better create an annotation that we can pass some lambda function to.
My third thought: Can't assign lambda functions. BUT can assign classes. Yeah.

So I conjured this up (also attached as a file):
Create an annotation wherein you can annotate a class that does this resolving/decoupling, i.e. return the Boolean instead of the MutableLiveData<Boolean>.
This way the user can - in his own code - decide how special cases like this are resolved at preprocess/compile time.


And the slight changes we have to make to the code below:
  • Find a proper name for that Lambda
  • Adjust the FunctionalInterface "Ionizer" to what we need
    • extend its parameters
    • or even add generic argument to it if needed
  • Write better implementations (instead of Maximator and Minimator) that produce usable code and fit into the Lombok Java code analyzer / replacer.
  • Place and call the introspect() method in Lombok
The only question is if something like this does not already exist in one form or the other...?



So here's the code behind this basic idea:


import java.lang.annotation.Inherited;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

public class LambdaToAnnotation {



@FunctionalInterface
interface Ionizer { // any interface needed to work with Lombok annotation processing
String eval(String pValue);
}



static class Maximator implements Ionizer {
@Override public String eval(final String pValue) {
return pValue.toUpperCase();
}
}
static class Minimator implements Ionizer {
@Override public String eval(final String pValue) {
return pValue.toLowerCase();
}
}



@java.lang.annotation.Target(value = { java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD })
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@Inherited
static public @interface IonizerAnnotation {
Class<? extends Ionizer> value();
}



static class TestClass {
@IonizerAnnotation(Maximator.class) public String mName;
@IonizerAnnotation(Minimator.class) public String mCity;
@IonizerAnnotation(Minimator.class) public int mAge;

public TestClass(final String pName, final String pCity, final int pAge) {
mName = pName;
mCity = pCity;
mAge = pAge;
}
}



static public String introspect(final Object pObject, final String pVariableName) throws NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
final Field nameField = pObject.getClass().getDeclaredField(pVariableName);
final Class<?> nameFieldType = nameField.getType();
if (nameFieldType != String.class) throw new IllegalArgumentException("Variable name [" + pVariableName + "] does not point to a valid String member variable!");

final IonizerAnnotation annot = nameField.getAnnotation(IonizerAnnotation.class);
final Class<? extends Ionizer> ionizerClass = annot.value();
final Ionizer ionizer = ionizerClass.getDeclaredConstructor().newInstance();
final String value = (String) nameField.get(pObject);
return ionizer.eval(value);
}



public static void main(final String[] args) throws NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
final TestClass tc = new TestClass("Peter Lustig", "Passau", 72);
System.out.println("Name:\t" + introspect(tc, "mName"));
System.out.println("City:\t" + introspect(tc, "mCity"));
// System.out.println("Beer:\t" + introspect(tc, "mBeer"));
// System.out.println("Age:\t" + introspect(tc, "mAge"));
}



}

--
You received this message because you are subscribed to the Google Groups "Project Lombok" group.
To unsubscribe from this group and stop receiving emails from it, send an email to project-lombo...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/project-lombok/b81441dc-8b6e-411b-9a5f-bff6562e2572n%40googlegroups.com.


--
Christian Becker
+49.176.2238 9755
chris.b...@gmail.com

LambdaToAnnotation.java
Reply all
Reply to author
Forward
0 new messages