Java 值为null的引用类型的类型?

Java 值为null的引用类型的类型?,java,null,reference-type,Java,Null,Reference Type,根据: 4.5.2参考类型的变量 引用类型可以保存null引用 当赋值为null时,是否可以检索引用类型的声明类型 具体地说,在使用反射的方法中,我希望该方法是空安全的,并作用于原始声明的类型(尽管我知道以下代码段不起作用),例如: String referenceType = null; MyReflectionClass.reflectionMethod(referenceType); ... public static void reflectionMethod(Object refer

根据:
4.5.2参考类型的变量
引用类型可以保存
null
引用

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

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

String referenceType = null;
MyReflectionClass.reflectionMethod(referenceType);
...
public static void reflectionMethod(Object referenceType) {
   Class<?> declaredType = referenceType.getClass();
}
String referenceType=null;
MyReflectionClass.reflectionMethod(referenceType);
...
公共静态void reflectionMethod(对象引用类型){
类declaredType=referenceType.getClass();
}
如果必要的话,我不会反对使用泛型将type
T
而不是
Object
作为声明的参数类型

Edit:我知道
.getClass()
对实例有效,而不是声明的类型。我想知道是否有可能要求引用它的声明类型。因为类层次结构是静态的,所以获取这些信息应该没有问题

Edit2:在这里,情况很清楚:
Java只是传递值,所以即使使用了引用类型,也总是像传递值(对象实例)一样处理它(即使内部仅传递对象指针)。这意味着Java实际上没有一个知道其类型的引用类型(至少就程序员而言),它都在值实例中。

因此,无法确定任何
null
值的类型。

您误解了
getClass()
不会告诉您声明的变量类型,它会告诉您对象的类型(如果有)。让我们停下来,退一步一分钟——如果它这样做了,你会引用哪个变量?原始变量?方法参数?它在过程中传递的任何其他变量?那太疯狂了。

你找不到
null
引用的声明类型。泛型也帮不了什么忙,因为它们在编译时会被删除。如果您需要知道
null
情况下的类型,那么您必须以某种方式在运行时传递该类型。

一句话,不。尽管如此,尝试查找null引用的成员没有多大意义,因为null意味着没有任何内容。您最好不允许null作为输入,可能是抛出一个
NullPointerException

如果必须处理null,那么最好的方法可能是显式地传递类引用(或者更好的是,直接引用所讨论的方法)

public static void reflectionMethod(对象参数,类referenceType)//referenceType不允许为null
{
//…无需尝试从对象回溯类型
}

如果只能得到空值,那么很难(除非有其他限制条件,否则不可能)比非常幸运的猜测做得更好。

不,不是。在您的示例中,当尝试调用null reference referenceType上的方法时,将出现null指针异常

更具体地说,这是不可能的,因为具体类型在编译时不一定是已知的,例如,如果我声明一个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
}
objectreferencetype=新字符串(“我是字符串”);
MyReflectionClass.reflectionMethod(referenceType);
...
公共静态void reflectionMethod(对象引用类型){
类declaredType=referenceType.getClass();//返回String.Class
}

我不确定这在您的上下文中是否有用,但是您可以使用泛型来实现类似的功能-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("");
    }
}
包装尖峰;
导入java.lang.reflect.ParameterizedType;
公共类反射方法{
公共抽象静态类GenericType{
公共类typedClass(){
ParameteredType pType=(ParameteredType)getClass().getGenericSuperclass();
返回(类)pType.getActualTypeArguments()[0];
}
公共空隙反射法(TO){
System.out.println(“类:“+typedClass());
}
}
/**
*@param args
*/
公共静态void main(字符串[]args){
GenericType gs=新的GenericType(){
};
gs.反射法(“”);
}
}

泛型并不总是在编译时被擦除,但在本例中它们是被擦除的。在本例中,我试图找出要调用的方法:
Class.getMethod(String,Class…
,其中用于调用目标方法的
null
参数值可能有效。在这里,这样做是有意义的。如果可以的话,直接传递类引用,而不是试图从不适用于null的对象(请参阅更新的答案)追溯对象类型,这就是这里要问的。它适用于null。请注意,参数不用于访问类型。不幸的是,这甚至不适用于非空值。关键是我试图动态地获取引用类型的类型。只有在可以静态实例化泛型
括号中的类型时,这才有效。如果我可以这样做,那么我也可以静态地设置参数列表中的类型。如果在方法调用时不知道变量的类型,则此操作将不起作用。在运行时,引用类型仍应知道它是一个
字符串
,否则它将无法与值类型区分。@leet3lite:String对象知道它是字符串,但对象引用不知道它引用的对象是字符串。它只引用任何对象。因此,如果没有对象(空引用),就无法判断它的类型
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("");
    }
}