Wrapper和Reflection之间有什么区别

时间:2010-01-07 09:40:44

标签: c# java reflection wrapper

我对反射和包装器非常困惑,我知道反射可以将对象反射到另一个对象类型中,包装器可以将原始类型转换为对象。这是对的吗?

4 个答案:

答案 0 :(得分:1)

你的反思概念是错误的。 Reflection允许程序在运行时调查自己的类。例如,你得到一个(在编译时)未知类的对象,并找出它有哪些字段和方法。

包装器只是一个接受对象并包装它的类,即它添加(几乎)没有新功能,但是暴露了与原始类不同的接口。一个特例是原始类型的包装器;因为原始类型不是某些语言中的对象,例如Java,这些基本类的包装类允许处理像对象这样的原始类型。

答案 1 :(得分:1)

  

包装器可以将基元类型转换为对象

嗯,你好像很困惑。 “包装器”通常是一些隐藏API(“包装”它)的代码,以简化调用等。您可能正在考虑autoboxing,它允许您使用基本类型,如相应的对象,反之亦然。

  

反射可以将对象反映到另一个对象类型

不,反射允许您在运行时检索有关可用类及其成员的信息,并调用它们的功能,即使它们在编译时不可用。

有关详细信息,请参阅http://java.sun.com/docs/books/tutorial/reflect/。请阅读此内容,如果您仍然感到困惑,请回来,并提出新问题。

答案 2 :(得分:1)

围绕另一个对象的包装器wrap可能隐藏使用原始对象的一些复杂性/提供不同的命名约定等。

原谅C#语法和相当人为的例子

class SimplePerson{

    ComplexPerson _person;

    public void WalkForward (int steps){

        for (int i = 0; i < steps; i ++){
            _person.LeftFoot ();
            _person.MoveFoot ();
            _person.PlaceFoot ();
        }
    }
    // More methods
}

另一方面,反射可用于从对象中检索方法/字段/属性和元数据。

再次原谅C#

SimplePerson _person;

Console.WriteLine ("Class {0} has the following methods:", _person.GetType().Name); 

foreach (var method in _person.GetType().GetMethods()){
    Console.WriteLine ("\t {0}", method.Name);
}

应该给出类似的输出(显然取决于类)

  

Class SimplePerson具有以下方法:

    Eat         
    WalkForward
    RunForward

答案 3 :(得分:0)

  

我知道反射可以将对象反映到另一个对象类型

不是真的。反射用于在运行时动态访问/修改对象。

假设您拥有类Foo,您可以使用以下命令以编程方式创建实例:

Object o = new Foo();

但您也可以在运行时使用名称:

创建实例
 public Object createInstanceOf( String className ) 
              throws InstantiationException,
                      IllegalAccessException { 
       return Class.forName( className ).newInstance();
 }

 Object o = createInstanceOf( "Foo" ) ;

这基本上就是reflection的全部内容。

  

包装器可以将基元类型转换为对象

一般来说,包装器只是......很好地包装另一个对象。特别是对于Java原语而言,Java包装器会包装原语,因此它们可以用作任何其他常规对象,例如将int传递给接收对象的对象,您必须使用包装器:< / p>

public void somethingWith( Object o ) {}

....

int i = 1234;

somethingWith( new Integer( i ) );

在java 1.5之前,您无法在不必显式创建包装器实例的情况下调用方法somethingWith

今天使用autoboxing,编译器会为您执行此操作,您可以直接调用:

somethingWith( 1234 ) ;

我希望这会有所帮助,而不会让您更加困惑。