是否有可能在Java中获取未实例化变量的类型?

时间:2014-11-29 22:58:28

标签: java oop pointers object

是否有可能获得在Java中声明(但未实例化)的变量的类型? 例如:

public class Foo {

     FooTwo foo2;
     FooTwo foo3;
     FooThree foo4;

     public static void main(String[] args) {
         if (foo2.getClass() == foo3.getClass()) {
             System.out.println("foo2 is the same type as foo3");
         }
         if (foo3.getClass() == foo4.getClass()) {
             System.out.println("foo3 is the same class as foo4");
         }
     }
}

输出:

foo2 is the same type as foo3

显然,方法getClass()不适用于未实例化的变量,因此该代码不起作用。我假设我要查找的信息存储在变量(指针?)的某处,以确保类型安全,并且可以访问它。 是否可以实现此比较?

原因: 我有一个包含几个声明变量的类。这些变量应该指向存储在另一个类的ArrayList中的对象。我正在尝试创建一个方法,将初始化(但未实例化)的变量作为参数,扫描arraylist以查找与初始化变量的类型匹配的对象,并将变量设置为对象(使变量指向对象)。

另外:系统的要点是删除类的构造函数中的耦合。无法立即或在构造函数中实例化对象。

2 个答案:

答案 0 :(得分:7)

首先,您需要了解表达式的类型与值的运行时类型之间的区别。例如,考虑以下代码:

List<String> list = new ArrayList<String>();
System.out.println(list.getClass());

上面的代码打印class java.util.ArrayList,而不是java.util.List<java.lang.String>,因为getClass()返回list引用的对象的运行时类型,而不是{{1}的类型本身。

因此,对未初始化的变量调用list是没有意义的,因为它没有返回运行时类型的值。


  

我正在尝试创建一个方法,该方法将初始化(但未实例化)的变量作为参数,[...]并将变量设置为对象(使变量指向对象)。

由于Java是一种按值传递的语言,因此它没有公开修改作为参数传入的变量的方法。例如,请考虑以下方法:

getClass()

上述方法绝对没有。它有一个局部变量public void doNothing(Object obj) { obj = "obj"; } ,它最初包含传入的任何引用,然后更改为引用字符串obj;但是这个改变没有效果,因为在那之后没有任何实际使用局部变量"obj"。特别是,此方法对传入的任何引用都没有任何影响。

你最接近的是使用反射;如果您的方法采用type Field的实例,它可以检查字段的声明类型,并将字段设置为其选择的值。

答案 1 :(得分:2)

你可以使用反射做类似的事情。这是一个示例代码段。但如果您更详细地解释一下您的用例,可能有更好的方法来解决您的问题。

import java.lang.reflect.Field;

public class Foo {

    static FooTwo foo2;
    static FooTwo foo3;
    static FooThree foo4;

    public static void main(String[] args)  {

        try {
            Field foo2Field = Foo.class.getDeclaredField("foo2");
            Field foo3Field = Foo.class.getDeclaredField("foo3");
            Field foo4Field = Foo.class.getDeclaredField("foo4");

            if (foo2Field.getType().equals(foo2Field.getType())) {
                System.out.println("foo2 is the same type as foo3");
            }
            if (foo3Field.getType().equals(foo4Field.getType())) {
                System.out.println("foo3 is the same class as foo4");
            }

        } catch (NoSuchFieldException e) {
            e.printStackTrace();
            // TODO handle this if this can happen
        } catch (SecurityException e) {
            e.printStackTrace();
            // TODO handle this appropriately
        }

    }

}

class FooTwo {

}

class FooThree {

}