0

那么我正在尝试学习java MVC模式,但我无法理解以下方法:

protected void setModelProperty(String propertyName, Object newValue) {

        for (AbstractModel model: registeredModels) {
            try {

                Method method = model.getClass().
                    getMethod("set"+propertyName, new Class[] {
                                                      newValue.getClass()
                                                  }
                             );
                method.invoke(model, newValue);

            } catch (Exception ex) {
                //  Handle exception
            }
        }
    }

我不明白:

Method method = model.getClass().
                    getMethod("set"+propertyName, new Class[] {
                                                      newValue.getClass()
                                                  }
                             );

所以在getMethod中我们是根据属性来检索(setSomething)方法名,那么下面的“东西”就是属性值newValue,用这个我完全看不懂的花哨的表达式来表达。

new Class[] <--- 所以这是一个类数组???next { newValue.getClass() } <---- 好的,通过调用方法获取括号中的类名,但是分号呢?一定有一些我不明白的特殊结构,它看起来像一个类,但如果没有分号,那肯定是不同的......请大家解释一下这是什么......

4

4 回答 4

2

要回答有关数组语法的问题,这就是您在 Java 中定义数组的方式:

int[] intArray = new int[] {1, 2, 3};
String[] stringArray = new String[] {"a", "b", "c"};
Class classArray = new Class[] {Integer.class, String.class, Double.class};

因此,表达式是一个实例new Class[] {newValue.getClass()}数组,包含一个元素: 的结果,因此是 的类。ClassnewValue.getClass()newValue

请注意,我不知道您从哪里获得此代码,但我不会称其为好代码:

  • 它使用反射,这在大多数情况下是个坏主意;
  • 它不尊重 JavaBean 约定,也不使用java.beansAPI 来访问 setter 方法。
  • 它不支持继承,这意味着您只能setFoo(Object o)使用 Object 类型的对象(而不是 String、Integer 或其他)进行调用。
于 2012-04-05T10:19:36.170 回答
2

与:

new Class[] { newValue.getClass() }

您正在指定一个内联类数组,并将其传递给 getMethod 的参数。

由于混合了“Class”,它可能会更令人困惑,但它与以下内容一样有效:

Integer[] bla = new Integer[]{1,2,3,4};

getMethod 接收您在类中查找的方法的名称作为参数,以及指定所述方法的参数的类数组。例子:

getMethod("setValues", new Class[]{String.class, Integer.class}

将寻找如下方法:

public Something setValues(String p1, Integer p2)

即使它存在于同一个类中,它也不匹配,例如:

public Something setValues(String p1)

或任何其他变体。

于 2012-04-05T10:15:24.587 回答
1

这是一种抽象的编码方式,老实说,如果有可能(例如通过使用模板),我会不鼓励这种工作方式,尤其是在初学者级别。无论如何,我会尽力解释。

Java中的所有类也是Class类的对象。并且所有方法都是类 Method 的对象。您可以像操作任何其他对象一样操作这些对象,方法是调用它们的方法并将它们用作其他方法的参数等等。这样,您只需知道其名称为字符串即可完美地实例化一个类。方法也一样:你可以通过简单地知道它的名字作为一个字符串来调用一个方法。

现在让我们看看你的代码。快速浏览一下Java API 中的这个条目,了解这部分的简要说明getMethod("set"+propertyName, new Class[] {newValue.getClass()});

假设您要调用方法setParameter(int parameterValue) {...}propertyName在这种情况下,我们使用set to"Parameter"newValueset to a certain integer调用您的方法123。现在"set"+propertyName结果是setParameter,这是我们方法的名称。newValue.getClass()Integer,因为那是什么123

getMethod需要一个类数组,因为可能存在许多具有相同名称的方法,但参数的数量和类型不同(例如,该方法也有可能setParameter(double parameterValue) {...}存在)。所以我们把它newValue.getClass()放在一个只有一个项目的数组中,通过编写new Class[] {newValue.getClass()}.

你有它:你Method通过调用检索一个对象

Method method = model.getClass(). getMethod("set"+propertyName, new Class[] {newValue.getClass()});

然后使用 调用该方法method.invoke(model, newValue);,这只是一种动态调用方式setParameter(123)

于 2012-04-05T10:25:32.653 回答
1

假设,您调用该方法

setModelProperty("Key", "value");

然后循环中的代码将在所有注册模型中搜索带有签名的方法

<any modifiers> <any returntype> setKey(String value);

并在下一行调用该方法。

它将使用属性值来构造一个 setter 方法名称和值类来获取一个Class实例。该getMethod方法采用一组类只是因为我们希望能够找到具有多个参数的方法。

于 2012-04-05T10:07:31.537 回答