10

根据: http: //java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html
4.5.2 引用类型的变量
引用类型可以持有一个null引用。

当赋值为 时,是否可以检索引用类型的声明类型null

具体来说,在使用反射的方法中,我希望该方法是 null 安全的并作用于原始声明的类型(尽管我知道以下代码片段不起作用),例如:

String referenceType = null;
MyReflectionClass.reflectionMethod(referenceType);
...
public static void reflectionMethod(Object referenceType) {
   Class<?> declaredType = referenceType.getClass();
}

如有必要,我不会反对使用泛型来拥有类型T而不是Object声明的参数类型。

编辑:我知道这.getClass()适用于实例,而不是声明的类型。我想知道是否可以询问它声明的类型的引用。由于类层次结构是静态的,因此获取该信息应该没有问题。

Edit2:在这里,情况很清楚:Java是“按引用传递”还是“按值传递”?
Java 只是按值传递,所以即使使用了引用类型,它也总是像传递值(对象实例)一样被处理(即使内部只传递一个对象指针)。这意味着Java实际上并没有一个知道它的类型的引用类型(至少就程序员而言),它都在值实例中。
因此不可能确定任何null值的类型。

4

5 回答 5

8

一句话,没有。但是,尝试查找 null 引用的成员并没有多大意义,因为 null 意味着没有任何东西。你可能最好只禁止 null 作为输入,可能是通过抛出一个NullPointerException.

如果必须处理 null,也许最好的方法是显式传递类引用(或者更好的是,直接引用相关方法)。

public static void reflectionMethod(Object param, Class<?> referenceType) // null is dis-allowed for referenceType
{
    // ... no need to try to back-track the type from an object
}

如果您只能获得空值,那么很难(除非施加其他约束,否则不可能)做得比非常幸运的猜测要好得多。

于 2011-04-19T07:30:07.907 回答
7

你误会了。getClass()不会告诉你变量的声明类型,它会告诉你对象的类型,如果有的话。让我们停下来后退一步——如果是这样,你会指哪个变量?原始变量?方法参数?它沿途经过的任何其他变量?那将是完全的疯狂。

于 2011-04-19T07:27:29.313 回答
3

您找不到null引用的声明类型。泛型也无济于事,因为它们在编译时就被删除了。如果您需要了解这种情况,则必须以某种方式在运行时传递类型null

于 2011-04-19T07:27:35.057 回答
0

不它不是。在您的示例中,当您尝试在空引用 referenceType 上调用方法时,您将获得空指针异常。

更具体地说,这是不可能的,因为在编译时不一定知道具体类型,例如,如果我声明 Object 类型的引用并将其分配给 String,那么您的方法应该发现该对象是 String 而不是 Object。

Object referenceType= new String("I'm a string");
MyReflectionClass.reflectionMethod(referenceType);
...
public static void reflectionMethod(Object referenceType) {
   Class<?> declaredType = referenceType.getClass(); // returns String.class
}
于 2011-04-19T07:38:34.823 回答
0

我不确定这对您的上下文是否有帮助,但您可以使用泛型来实现类似的东西 - Java 1.5+ 保留子类的类型信息。

package spikes;

import java.lang.reflect.ParameterizedType;

public class ReflectMethod {
    public abstract static class GenericType<T> {
        public Class typedClass() {
            ParameterizedType pType = (ParameterizedType) getClass().getGenericSuperclass();
            return (Class) pType.getActualTypeArguments()[0];
        }

        public void reflectMethod(T o) {
            System.out.println("Class: " + typedClass());
        }
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        GenericType<String> gs = new GenericType<String>() {

        };
        gs.reflectMethod("");
    }
}
于 2011-04-19T07:51:22.903 回答