Меня это удивляет!get vs getProperty in groovy
В соответствии с документом groovy, groovy может использовать метод getProperty для получения свойства объекта. Поэтому, когда я хочу изменить поведение получения свойства на специальный объект, я использую класс категории для переопределения метода getProperty. Однако это не работает. Наконец, я обнаружил, что groovy framework использует метод get в классе категории для получения свойства, даже если объект не является картой. Мой вопрос в том, что это баг или groovy просто так работает.
Это категория категории.
class DynaBeanExtension {
public static void setProperty(DynaBean bean, String propertyName, def newValue) {
try {
PropertyUtilsBean pu = null;
if (bean instanceof CustomWrapDynaBean) {
pu = bean.propertyUtilsBean;
}
if (pu != null) {
pu.setProperty(bean, propertyName, newValue);
} else {
PropertyUtils.setProperty(bean, propertyName, newValue);
}
} catch (IllegalArgumentException ex) {
bean.propertyMissing(propertyName, newValue);
}
}
public static def getProperty(DynaBean bean, String propertyName) {
try {
PropertyUtilsBean pu = null;
if (bean instanceof CustomWrapDynaBean) {
pu = bean.propertyUtilsBean;
}
if (pu != null) {
return pu.getProperty(bean, propertyName);
} else {
return PropertyUtils.getProperty(bean, propertyName);
}
} catch (IllegalArgumentException ex) {
return bean.propertyMissing(propertyName);
}
}
public static def get(DynaBean bean, String propertyName) {
try {
PropertyUtilsBean pu = null;
if (bean instanceof CustomWrapDynaBean) {
pu = bean.propertyUtilsBean;
}
if (pu != null) {
return pu.getProperty(bean, propertyName);
} else {
return PropertyUtils.getProperty(bean, propertyName);
}
} catch (IllegalArgumentException ex) {
return bean.propertyMissing(propertyName);
}
}
Это тестовый код:
public static class TestSubClass {
private final int e = 3, f = 4;
private final Map<String, Object> m = new HashMap<>();
public int getE() {
return e;
}
public int getF() {
return f;
}
public Map<String, Object> getM() {
return m;
}
@Override
public String toString() {
return "TestSubClass{" + "e=" + e + ", f=" + f + ", m=" + m + '}';
}
}
public static class TestClass {
private final int a = 1;
private final TestSubClass b = new TestSubClass();
public int getA() {
return a;
}
public TestSubClass getB() {
return b;
}
@Override
public String toString() {
return "TestClass{" + "a=" + a + ", b=" + b + '}';
}
}
Map<String, String> pMap = new HashMap<>();
pMap.put("b.e", "c");
PropertyUtilsBean pu = new PropertyUtilsBean();
pu.setResolver(new ExResolver(pMap));
TestClass testObj = new TestClass();
DynaBean bean = new CustomWrapDynaBean(testObj, pu);
int c = use(DynaBeanExtension) {
bean.c;
}
Это код ExResolver:
public class ExResolver implements Resolver {
private static final char NESTED = '.';
private static final char MAPPED_START = '(';
private static final char MAPPED_END = ')';
private static final char INDEXED_START = '[';
private static final char INDEXED_END = ']';
private final Resolver resolver;
private final Map<String, String> pMap;
public ExResolver(Map<String, String> pMap) {
this(new DefaultResolver(), pMap);
}
public ExResolver(Resolver resolver, Map<String, String> pMap) {
this.resolver = resolver;
this.pMap = new HashMap<>(pMap);
}
private String resolveExpr(String expression) {
for (Map.Entry<String, String> entry : pMap.entrySet()) {
if (expression.startsWith(entry.getValue())) {
String to = entry.getValue();
if (expression.length() == entry.getValue().length()) {
return entry.getKey();
} else {
int toTest = expression.codePointAt(to.length());
if (toTest == NESTED || toTest == MAPPED_START || toTest == INDEXED_START) {
return entry.getKey() + expression.substring(to.length(), expression.length());
} else {
return expression;
}
}
}
}
return expression;
}
@Override
public int getIndex(String expression) {
expression = resolveExpr(expression);
return resolver.getIndex(expression);
}
@Override
public String getKey(String expression) {
expression = resolveExpr(expression);
return resolver.getKey(expression);
}
@Override
public String getProperty(String expression) {
expression = resolveExpr(expression);
return resolver.getProperty(expression);
}
@Override
public boolean hasNested(String expression) {
expression = resolveExpr(expression);
return resolver.hasNested(expression);
}
@Override
public boolean isIndexed(String expression) {
expression = resolveExpr(expression);
return resolver.isIndexed(expression);
}
@Override
public boolean isMapped(String expression) {
expression = resolveExpr(expression);
return resolver.isMapped(expression);
}
@Override
public String next(String expression) {
expression = resolveExpr(expression);
return resolver.next(expression);
}
@Override
public String remove(String expression) {
expression = resolveExpr(expression);
return resolver.remove(expression);
}
}
"получить" вызывается, а не "GetProperty"
Что больше , в реальной ситуации DynaBeanExtension
составлен с groovy. Построение боба составлено с помощью java. Затем, используя binding
, я поместил его в тестовый код, который представляет собой сценарий выполнения, выполняемый java-кодом.
ну вы можете добавить код на вопрос и описать там, что не работает – cfrick
нормально. Я помещаю код в ответ ответа –
нет, вы этого не делаете. пожалуйста, отредактируйте этот вопрос (http://stackoverflow.com/posts/30722700/edit). SO - это не форум, а сайт QA. – cfrick