具有默认(包)可见性覆盖的 Android 方法(不应该工作,但可以 - 为什么?) [英] Android method with default (package) visibility overriding (shouldn't work, but does - why?)

查看:24
本文介绍了具有默认(包)可见性覆盖的 Android 方法(不应该工作,但可以 - 为什么?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在研究 Android 中的 SVG 支持,并提出了这个库它声称它像原生一样支持 SVG.

I've been playing around with SVG support in Android and came up with this library which claims that it supports SVG just as it they were native.

因为我费了很大的劲才发现这真的不可能,所以我去看看这个家伙是如何做到的.所以我发现了他的 Resources 衍生物,他在其中声明了一个方法 (loadDrawable),该方法在基本 Resources 类中具有默认可见性.

Since I took great pains in discovering that this is not really possible, I went to see how this dude actually managed it. So I came upon his Resources derivative in which he declares a method (loadDrawable) that has default visibility in base Resources class.

有趣的是,通常 lint 只会报告您无法编写此方法,因为它会隐藏基本方法,但在这种特殊情况下(注意 缺少 @Override指令)这个方法被调用,就好像它是在基类中编写的一样.调用此方法的所有方法都将调用覆盖而不是原始方法.对于来自C++Pascal等经典编译器的我来说,这完全无法理解.

The funny thing is, normally lint would just report that you can't write this method since it would hide base method, but in this particular case (note the absense of @Override directive) this method gets to be called as if it were written in the base class. All the methods invoking this method will invoke the override instead of original method. For me coming from classic compilers such as C++ or Pascal, this is totally beyond comprehension.

基于此,我设法让我的 SVG 支持完全使用一次反射,并且对此感到非常高兴,但是:

Based on this, I managed to get my SVG support working completely with one single use of reflection and am super-happy about this, but:

为什么会这样?

推荐答案

看起来 Dalvik 解释器中存在一个错误,它允许覆盖包私有方法.显然,Google 意识到了这个问题(在 Jelly Bean 中?),因为 Dalvik 报告了一个警告,指出在这种情况下它错误地覆盖了包私有方法,而 ART 将其报告为错误并且无法编译它.正确的行为当然是允许它但不允许覆盖来自其他包的包私有方法,但看起来 Google 希望避免破坏依赖此行为的现有应用程序.

It looks like there is a bug in the Dalvik interpreter which allows package-private methods to be overridden. Apparently, Google recognized this issue (in Jelly Bean?), as Dalvik reports a warning that it is incorrectly overriding a package-private method in this case, and ART reports it as an error and fails to compile it. The correct behaviour would of course be to allow it but not allow overriding package-private methods from other packages, but it looks like Google want to avoid breaking existing applications that depend on this behaviour.

更新:现在正式在 6 月 16 日的 ART 文档更新中确认,尽管它指出 ART 发出警告而不是严重错误,如 velis 在问题评论中报告:

UPDATE: This is now officially confirmed in the ART documentation update on June 16, although it states that ART issues a warning instead of a critical error as velis reported in the comments on the question:

Dalvik 错误地允许子类覆盖包私有方法.在这种情况下 ART 会发出警告:

Dalvik incorrectly allowed subclasses to override package-private methods. ART issues a warning in such cases:

Android 4.1 之前,方法 void com.foo.Bar.quux()
会错误地覆盖
中的包私有方法com.quux.Quux

Before Android 4.1, method void com.foo.Bar.quux()
would have incorrectly overridden the package-private method in
com.quux.Quux

如果您打算在不同的包中覆盖类的方法,请将方法声明为 publicprotected.

If you intend to override a class's method in a different package, declare the method as public or protected.

这篇关于具有默认(包)可见性覆盖的 Android 方法(不应该工作,但可以 - 为什么?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆