Nella mia applicazione mi imbatto in un problema che quando un getter in una classe è predefinito in una sola interfaccia (funzione Java 8), non esiste una proprietà Java Beans come risultato. Cioè per il metodo normale invocazione funziona proprio come un metodo standard, ma per l'accesso tramite "proprietà" si comporta in modo diverso ... improvvisamenteIl metodo di default dell'interfaccia Java 8 non sembra dichiarare la proprietà
Qui è un banco di prova:
import java.beans.Introspector;
import java.util.Arrays;
import java.util.stream.Collectors;
import org.apache.commons.beanutils.PropertyUtils;
public class test
{
public static void main (String[] arguments) throws Exception
{
// Normal language-level invocation, works fine.
System.out.println (new Bean1().getFoo());
System.out.println (new Bean2().getFoo());
// Printing Java Beans properties; Bean2 doesn't have 'foo' property...
System.out.println (Arrays.stream (Introspector.getBeanInfo (Bean1.class).getPropertyDescriptors())
.map ((property) -> property.getName())
.collect (Collectors.joining (", ")));
System.out.println (Arrays.stream (Introspector.getBeanInfo (Bean2.class).getPropertyDescriptors())
.map ((property) -> property.getName())
.collect (Collectors.joining (", ")));
// First call behaves as expected, second dies with exception.
System.out.println (PropertyUtils.getProperty (new Bean1(), "foo"));
System.out.println (PropertyUtils.getProperty (new Bean2(), "foo"));
}
public interface Foo
{
default String getFoo()
{
return "default foo";
}
}
public static class Bean1 implements Foo
{
@Override
public String getFoo()
{
return "special foo";
}
}
public static class Bean2 implements Foo
{ }
}
Risultato:
special foo
default foo
class, foo
class
special foo
Exception in thread "main" java.lang.NoSuchMethodException: Unknown property 'foo' on class 'class test$Bean2'
at org.apache.commons.beanutils.PropertyUtilsBean.getSimpleProperty(PropertyUtilsBean.java:1257)
at org.apache.commons.beanutils.PropertyUtilsBean.getNestedProperty(PropertyUtilsBean.java:808)
at org.apache.commons.beanutils.PropertyUtilsBean.getProperty(PropertyUtilsBean.java:884)
at org.apache.commons.beanutils.PropertyUtils.getProperty(PropertyUtils.java:464)
at test.main(test.java:21)
Domande: faccio qualcosa di sbagliato o si tratta di un bug in Java? C'è una soluzione alternativa che non usare mai metodi predefiniti (per getter/setter) nel caso in cui potessi aver bisogno di accedervi come "proprietà" ad un certo punto dopo?
Ho sempre odiato Java "proprietà per convenzione" che tendono a rompersi perché si starnutisce nel modo sbagliato.
Sembra che questo sia coperto da [JDK-8071693] (https://bugs.openjdk.java.net/browse/JDK-8071693), non ancora corretto in nessuna versione di JDK. –
Sì, davvero. Spero che lo risolvano. – doublep
Sono stato morso da questo bug. Il bug di OpenJDK è programmato per Java 9, il che significa che dovremo aspettare almeno fino a settembre 2016 per essere corretto. Nel frattempo vorrei semplicemente creare un metodo delegato nella classe che ha bisogno della proprietà. –