了解这种实例化新对象的方式

时间:2011-06-21 21:41:35

标签: blackberry java-me

我刚刚开始开发BlackBerry,我按照一些教程熟悉UI对象等等,我看到/尝试过这个:

private MenuItem menuItemClose = new MenuItem(new StringProvider("Contacts"), 0, 0) {
    public void run() {
        onClose();
    }
};

我之前没有看到这种实例化对象的方式(考虑新的MenuItem),有人可以解释发生了什么吗?

实例化方法定义中的对象和“实例变量部分”之间的区别是什么?

3 个答案:

答案 0 :(得分:2)

这被称为“匿名内部阶级。”

匿名内部类是在另一个类中创建但未命名的类。它们通过它们的接口或抽象基类定义进行实例化,并在实例化的情况下内联它们缺少的实现。

在这种情况下,MenuItem是抽象的 - 它缺少run()方法。您将在第2-4行提供run()方法的实现。

请查看this JavaWorld article以获取有关内部类的各种类型和用法的更多信息。

至于你的问题的第二部分“在方法定义中实例化对象和在”实例变量部分“之间有什么区别呢?” - 区别在于范围,以及实例化对象时。

在实例化包含它们的对象时,会创建具有初始值的非静态成员变量。初始值赋值(初始化)也在那时执行。

当VM的类加载器加载类时,会创建并初始化具有初始值的静态成员变量。通过急切的ClassLoading,这将在应用程序的开始时发生。使用延迟的ClassLoading,这将在应用程序第一次引用类时发生。我相信默认情况下,大多数不属于Java运行时的类都是懒惰加载的。

静态和非静态成员变量都具有对象级范围,并且可以根据其访问修饰符(public / private / protected)由其他对象访问。

非静态成员变量是对象实例的一部分,因此当该实例是孤立的或超出范围时,它们被标记为垃圾回收。如果卸载包含它们的类,则仅对静态成员变量进行垃圾回收。只有在加载了所述类的ClassLoader实例被垃圾回收时才会出现这种情况。有关详细信息,请参阅this question

当该行作为正常方法执行的一部分执行时,将创建并初始化具有初始值的局部变量(在方法中定义的变量)。一旦它们超出范围(在包含它们的方法完成后),它们被标记为垃圾收集(销毁)。

答案 1 :(得分:1)

这将创建一个匿名内部类,它扩展MenuItem并覆盖run方法。它是标准的Java,与Blackberry无关。

答案 2 :(得分:1)

当你在方法调用中定义一个新的内部类时,它被称为“匿名内部类”。当您在初始方法调用之后不需要对对象的引用时,匿名内部类很有用。

final Object obj = new Object(); // Standard instantiation
System.out.println(obj); // Prints java.lang.Object@5c005c

// Anonymous inner class
System.out.println(new Object() { }); // Prints Foo$1@2500250

// Anonymous inner classes work with interfaces too
new Thread(new Runnable() {

    @Override
    public void run() {
        // Runnable is an interface
    }

}).start();

这是一种非常常见的模式,可用于定义“一次性使用”对象,可能会牺牲可读性。