在尝试使用 默认访问器 (例如:)覆盖方法时,遇到一种奇怪的行为void run()
。根据Java规范,如果类属于同一包,则类可以使用或覆盖基类的默认成员。从同一个类加载器加载所有类时,一切工作正常。但是,如果我尝试从
单独的 类加载器中加载子类,则多态性将无法正常工作。
这是示例:
App.java:
import java.net.*;
import java.lang.reflect.Method;
public class App {
public static class Base {
void run() {
System.out.println("error");
}
}
public static class Inside extends Base {
@Override
void run() {
System.out.println("ok. inside");
}
}
public static void main(String[] args) throws Exception {
{
Base p = (Base) Class.forName(Inside.class.getName()).newInstance();
System.out.println(p.getClass());
p.run();
} {
// path to Outside.class
URL[] url = { new URL("file:/home/mart/workspace6/test2/bin/") };
URLClassLoader ucl = URLClassLoader.newInstance(url);
final Base p = (Base) ucl.loadClass("Outside").newInstance();
System.out.println(p.getClass());
p.run();
// try reflection
Method m = p.getClass().getDeclaredMethod("run");
m.setAccessible(true);
m.invoke(p);
}
}
}
outside.java:应位于单独的文件夹中。否则,类加载器将是相同的
public class Outside extends App.Base {
@Override
void run() {
System.out.println("ok. outside");
}
}
输出:
class App$Inside
ok. inside
class Outside
error
ok. outside
因此,我称Outside#run()
我得到了Base#run()
(输出中出现“错误”)。反射正常工作。
怎么了?还是预期的行为?我能以某种方式解决这个问题吗?
从Java虚拟机规范:
5.3创建和加载
…
在运行时,类或接口的确定不仅取决于其名称,还取决于对:其完全限定的名称及其定义的类加载器。每个此类或接口都属于一个 运行时包
。类或接口的运行时包由包名称以及类或接口的定义类加载器确定。5.4.4访问控制
… 当且仅当满足以下任一条件时,类或接口D才 可以访问
字段或方法R : __
- …
- R是
protected
包私有的或包私有的(即,不是public
nor
protected
也不是private
),并且由与D相同的运行时包中的类声明。
问题内容: 我试图摆脱Java继承的束缚,并且了解到,当重写子类中的方法(和隐藏字段)时,仍然可以使用“ super”关键字从父类中访问它们。 我想知道的是,是否应将“ super”关键字用于非重写方法? 有什么区别(对于非覆盖方法/非隐藏字段)? 我在下面整理了一个例子。 和 具体来说,鉴于尚未被覆盖,应使用或?。 我想知道是否应该在访问超类的字段或方法的所有实例中使用super(以在代码中显示
本文向大家介绍Android调用系统默认浏览器访问的方法,包括了Android调用系统默认浏览器访问的方法的使用技巧和注意事项,需要的朋友参考一下 一、启动android默认浏览器 这样子,android就可以调用起手机默认的浏览器访问。 二、指定相应的浏览器访问 1、指定android自带的浏览器访问 2、启动其他浏览器(当然该浏览器必须安装在机器上) 只要修改以下相应的packagename
我想通过创建一个具体实现类的对象来执行接口中默认方法的定义体,该对象也覆盖了该方法。无论我是直接创建具体实现类的对象,还是通过动态绑定/多态,实现类中定义/重写的主体都只是得到执行。请看下面的代码 我想知道如何在控制台内部界面银行打印以下内容--loan()
问题内容: 我已经能够覆盖所有名称以“ android:”为前缀的主题,但是Android themes.xml还定义了似乎无法被覆盖的属性。例如: colorTheground是在Theme.Light xml中定义的,但是在此处添加它可以使我 错误。如何为整个应用程序覆盖该样式? 问题答案: 您可以用修改属性(如)的方式覆盖标准属性,只是不要忘记添加如下前缀:
问题内容: 我想覆盖Java外观。我只想显示不同的按钮。 我想要Windows Look and Feel的所有功能,但仅按钮有所不同。希望你明白我的意思。 还告诉我如何制作圆形的JtabbedPane ??? 问题答案: 自定义GUI类 调用您的自定义GUI类
问题内容: 我有一个模板与此: Django自动将此翻译为Terminarsesión西班牙语。但是,我想将其翻译为Cerrarsesión。 我试图将此文字添加到.po文件中,但是在编译消息时出现错误,指出该文字重复。 有没有一种方法可以更改/覆盖默认的Django翻译? 谢谢。 问题答案: 最简单的方法是收集在django.contrib.admin语言环境文件夹中找到的.po文件,然后重新编