繁体   English   中英

在Java方法中定义的访问类

[英]Access class defined in method in Java

在Java中,是否可以通过某种方式(反射等)访问method中定义的类? 如何?

例如,我想在下面的示例中创建InnerClass的实例:

class Example {
    public void outerMethod() {
        class InnerClass {
            double d = 0;
        }
    }

    public void testMethod() {
        outerMethod::InnerClass instance = new outerMethod::InnerClass();
    }
}

感谢您的回答。

不,那是不可能的。 在方法内部声明的名称只能在方法本身内部引用。 本地类(以您的情况为例)在Java 8语言规范的14.3节中定义。

https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-Block

从技术上讲是可能的。
实际上,这是一种hack,您应该在生产代码中避免这种做法。

例:

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

class Example {

     public void outerMethod() {

        class InnerClass {

            private double d = 7.62;

            @Override
            public String toString() {
                return String.format("[%s] d = %f", this.getClass().getName(), d);
            }

        }

    }

    public void testMethod() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {

        final Class<?> clazz = Class.forName("Example$1InnerClass");
        final Constructor<?> constructor = clazz.getDeclaredConstructor(Example.class);
        constructor.setAccessible(true);
        final Object instance = constructor.newInstance(this);

        System.out.println(instance);
    }

    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
         Example instance = new Example();
         instance.testMethod();
    }

}

在这里,我们首先通过其名称为本地类获取Class<?>
本地类名称生成规则是编译器实现的详细信息,并且可能会有所不同。 AFAIK javacECJ使用不同的方法。
然后,我们通过反射获得感兴趣的类的构造函数。
由于类未明确定义构造函数,因此编译器会自动生成该构造函数,并且该构造函数不是公共的。 因此,我们在这里使用getDeclaredConstructor()方法。
由于此类不是静态的(局部类不能静态定义),所以构造函数的第一个也是唯一的参数是外部类引用。 Example在我们的例子。
之后,我们通过调用constructor.newInstance(this)创建一个类的实例。
this作为参数传递给构造函数。 请参阅上面有关构造函数参数的注释。

最后,我们隐式调用InnerClass::toString()打印刚创建的对象

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM