我刚刚开始开发BlackBerry,我按照一些教程熟悉UI对象等等,我看到/尝试过这个:
private MenuItem menuItemClose = new MenuItem(new StringProvider("Contacts"), 0, 0) {
public void run() {
onClose();
}
};
我之前没有看到这种实例化对象的方式(考虑新的MenuItem),有人可以解释发生了什么吗?
实例化方法定义中的对象和“实例变量部分”之间的区别是什么?
答案 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();
这是一种非常常见的模式,可用于定义“一次性使用”对象,可能会牺牲可读性。