MVC(模型视图控制器);请解释一下这个方法

时间:2012-04-05 10:02:01

标签: java model-view-controller

我正在尝试学习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)方法名称,然后下面的“thing”是属性值newValue,在这个花哨的表达式中表达,我根本不理解。

new Class[]< ---所以它是一个类数组??? next { newValue.getClass() }< ----好的,通过调用方法获取括号中的类名,但分号怎么样?必须有一些我不理解的特殊结构,它看起来像一个类,但如果没有分号,那一定是不同的......人们解释我这是什么意思......

4 个答案:

答案 0 :(得分:2)

使用:

new Class[] { newValue.getClass() }

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

由于在混音中使用“Class”,可能会有点混乱,但它与以下内容一样有效:

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

getMethod接收您在Class中查找的方法的名称,以及指定所述Method的参数的Classes类。例如:

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

将寻找类似的方法:

public Something setValues(String p1, Integer p2)

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

public Something setValues(String p1)

或任何其他变体。

答案 1 :(得分: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()}因此是Class个实例的数组,包含一个元素:newValue.getClass()的结果,因此是newValue的类。

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

  • 它使用反射,这在大多数情况下是一个坏主意;
  • 它不遵守JavaBean约定,也不使用java.beans API来访问setter方法。
  • 它不支持继承,这意味着您只能使用Object类型的对象(而不是String,Integer或其他)调用setFoo(Object o)

答案 2 :(得分:1)

假设您调用类似

的方法
setModelProperty("Key", "value");

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

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

并在下一行调用该方法。

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

答案 3 :(得分:1)

这是一种抽象的编码方式,说实话,如果可以这样做(例如通过使用模板),我会劝阻这种工作方式,特别是在初学者级别。无论如何,我会试着解释一下。

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

现在让我们来看看你的代码。请快速查看Java API中的this entry,以获取对此部分getMethod("set"+propertyName, new Class[] {newValue.getClass()});的简要说明。

假设您要调用方法setParameter(int parameterValue) {...}。在这种情况下,我们会将您的方法调用propertyName设置为"Parameter"newValue设置为某个整数123。现在"set"+propertyName会生成setParameter,这是我们方法的名称。 newValue.getClass()提供了Integer,因为123就是这样。

getMethod需要一个Classes数组,因为可能存在许多具有相同名称的方法,但参数的数量和类型不同(例如,方法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)的动态方式。