我的界面中的静态最终值有奇怪的行为:
public interface IDictionaryErrorTypes {
final static int ERROR_UNKNOWN = 0;
final static int ERROR_XML = 1;
final static int ERROR_CONNECTION = 3;
}
public interface IDictionaryListModel extends IDictionaryErrorTypes,
//... and other interfaces
{
}
public class DictionaryListModel implements IDictionaryListModel {
// ... some code ...
private int getErrorCode(Exception error) {
// determinate the error code
if (error instanceof ParserConfigurationException
|| error instanceof SAXException
|| error instanceof SAXParseException) {
return ERROR_XML;
} else if (error instanceof UnknownHostException
|| error instanceof MalformedURLException
|| error instanceof IOException) {
return ERROR_CONNECTION;
}
return ERROR_UNKNOWN;
}
现在当我运行应用程序ERROR_XML时,ERROR_CONNECTION和ERROR_UNKNOWN值等于ZERO-0。在我看来这很奇怪。请看附图
如果我在我的模型IDictionaryErrorTypes.ERROR_CONNECTION
中使用它仍然具有相同的行为。但是,如果我删除"implements IDictionaryErrorTypes"
然后使用IDictionaryErrorTypes.ERROR_CONNECTION
它就可以了 - 常量值与它们听起来完全一样。
当我使用class而不是interface时,它也可以正常工作。
有人可以解释这种行为吗? (p.s.我使用android平台)
ps.s.(2)我还通过添加/删除“final”,“static”,“public”关键字进行了实验(这就是为什么图像和代码中的接口声明略有不同)。但行为是一样的
WORKING VERSION的smali代码(使用类而不是接口):
.method private getErrorCode(Ljava/lang/Exception;)I
.registers 3
.parameter "error"
.prologue
.line 145
instance-of v0, p1, Ljavax/xml/parsers/ParserConfigurationException;
if-nez v0, :cond_c
.line 146
instance-of v0, p1, Lorg/xml/sax/SAXException;
if-nez v0, :cond_c
.line 147
instance-of v0, p1, Lorg/xml/sax/SAXParseException;
if-eqz v0, :cond_e
.line 148
:cond_c
const/4 v0, 0x1
.line 154
:goto_d
return v0
.line 149
:cond_e
instance-of v0, p1, Ljava/net/UnknownHostException;
if-nez v0, :cond_1a
.line 150
instance-of v0, p1, Ljava/net/MalformedURLException;
if-nez v0, :cond_1a
.line 151
instance-of v0, p1, Ljava/io/IOException;
if-eqz v0, :cond_1c
.line 152
:cond_1a
const/4 v0, 0x3
goto :goto_d
.line 154
:cond_1c
const/4 v0, 0x0
goto :goto_d
.end method
// class instead of interface
.class public Ltj/zar/projects/kathtranslator/interfaces/common/IDictionaryErrorTypes;
.super Ljava/lang/Object;
.source "IDictionaryErrorTypes.java"
# static fields
.field public static final ERROR_CONNECTION:I = 0x3
.field public static final ERROR_UNKNOWN:I = 0x0
.field public static final ERROR_XML:I = 0x1
# direct methods
.method public constructor <init>()V
.registers 1
.prologue
.line 3
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
return-void
.end method
UNWORKING VERSION的smali代码:
.method private getErrorCode(Ljava/lang/Exception;)I
.registers 3
.parameter "error"
.prologue
.line 145
instance-of v0, p1, Ljavax/xml/parsers/ParserConfigurationException;
if-nez v0, :cond_c
.line 146
instance-of v0, p1, Lorg/xml/sax/SAXException;
if-nez v0, :cond_c
.line 147
instance-of v0, p1, Lorg/xml/sax/SAXParseException;
if-eqz v0, :cond_e
.line 148
:cond_c
const/4 v0, 0x1
.line 154
:goto_d
return v0
.line 149
:cond_e
instance-of v0, p1, Ljava/net/UnknownHostException;
if-nez v0, :cond_1a
.line 150
instance-of v0, p1, Ljava/net/MalformedURLException;
if-nez v0, :cond_1a
.line 151
instance-of v0, p1, Ljava/io/IOException;
if-eqz v0, :cond_1c
.line 152
:cond_1a
const/4 v0, 0x3
goto :goto_d
.line 154
:cond_1c
const/4 v0, 0x0
goto :goto_d
.end method
// interface
.class public interface abstract Ltj/zar/projects/kathtranslator/interfaces/common/IDictionaryErrorTypes;
.super Ljava/lang/Object;
.source "IDictionaryErrorTypes.java"
# static fields
.field public static final ERROR_CONNECTION:I = 0x3
.field public static final ERROR_UNKNOWN:I = 0x0
.field public static final ERROR_XML:I = 0x1
我清理了项目,将模拟器更改为真实设备并编写了一些测试。
这似乎是调试器问题:
如图所示,错误为“3”,ERROR_CONNECTION为“0”。并且设备实际上运行下一个字符串(绿色字符串),这意味着调试器认为3 == 0,但实际上它的3 == 3
调试器错误。
答案 0 :(得分:1)
你正在使用的任何调试器都在拖你(最有可能的答案),或者这是你正在使用的android SDK中的一个错误。您是否考虑过查看该方法实际返回的内容?
另请注意,无论您做什么,接口中的字段总是 static final
并且默认情况下是公共的 - 编译器会这样做。
public interface MyInterface
{
public static final int TEST = 3;
}
public interface MyInterface2 extends MyInterface
{
public final static int TEST2 = 5;
}
public class InterfaceTest implements MyInterface2
{
public void printInterfaceConstants()
{
System.out.println(TEST);
System.out.println(TEST2);
}
public static void main(String[] args)
{
InterfaceTest it = new InterfaceTest();
it.printInterfaceConstants();
}
}
输出:
3
5个
如前所述,首先不要这样做。实现细节不应该在接口中。
答案 1 :(得分:1)
我认为唯一的可能的解释是你在编辑/构建/运行/调试过程中遇到了一些问题,而你实际上运行的代码版本与你认为的不同。
这方面的证据是您已经反编译了您正在运行的相信的两个版本,并且反编译的代码清楚地显示了:
但是当你执行代码(据说)时,它的行为明显与那些字节码所说的不同。
我只能看到一个看似合理的解释:您没有执行那些字节码。相反,您正在执行不同版本的字节码。简而言之,您不需要重新编译/重建/重新部署需要完成的所有事情。
调试器输出很有意思,因为它倾向于证实这个假设,因为它似乎说你的可执行文件有一个接口的副本,其常量与源代码所说的不同。 (它也可能是调试器错误......但这太巧合了。)但是,调试器输出本身并不能解释应用程序的行为,因为应用程序没有使用这些值。