Java 7 语言功能与安卓

2022-08-31 06:33:12

只是想知道是否有人尝试过在Android上使用新的Java 7语言功能?我知道Android读取Java吐出的字节码并将其转换为dex。所以我想我的问题是它能理解Java 7的字节码吗?


答案 1

如果您使用的是Android Studio,则应自动启用Java 7语言,而无需任何补丁。试用资源需要API级别19 +,而NIO 2.0的东西丢失了。

如果您无法使用 Java 7 功能,请参阅@Nuno关于如何编辑 .build.gradle

以下内容仅用于历史兴趣。


Java 7的一小部分当然可以与Android一起使用(注意:我只在4.1上测试过)。

首先,你不能使用Eclipse的ADT,因为它是硬编码的,只有Java编译器1.5和1.6是兼容的。你可以重新编译ADT,但我发现除了重新编译整个Android之外,没有简单的方法可以做到这一点。

但你不需要使用Eclipse。例如,Android Studio 0.3.2IntelliJ IDEA CE和其他基于javac的IDE支持编译到Android您甚至可以使用以下功能将合规性设置为Java 8:

  • 文件→项目结构→模块→(在第 2 个窗格中选择模块)→语言级别→(选择“7.0 - 菱形、ARM、多捕获等”)

Enabling Java 7 on IntelliJ

这只允许Java 7语言功能,你几乎不能从中受益,因为一半的改进也来自库。您可以使用的功能是不依赖于库的功能:

  • 金刚石操作员(<>)
  • 字符串开关
  • 多重捕获(catch (Exc1 | Exc2 e))
  • 数字文本中的下划线 (1_234_567)
  • 二进制文本 (0b1110111)

这些功能不能使用:

  • -with-resources 语句 — 因为它需要不存在的接口 “java.lang.AutoCloseable”(这可以在 4.4+ 中公开使用)try
  • @SafeVarargs注释 — 因为 “java.lang.SafeVarargs” 不存在

...“然而”:)事实证明,尽管Android的库针对的是1.6,但Android源代码确实包含像AutoCloseable这样的接口,而像Closeable这样的传统接口确实继承了AutoCloseable(不过,SafeVarargs确实缺失了)。我们可以通过反思来确认它的存在。它们被隐藏仅仅是因为Javadoc有标签,这导致“android.jar”不包括它们。@hide

已经存在一个问题,即如何使用可用的隐藏和内部API构建Android SDK? 关于如何取回这些方法。您只需要将当前平台的现有“android.jar”引用替换为我们定制的引用,然后许多Java 7 API将变得可用(该过程类似于Eclipse中的过程。检查项目结构→ SDK。

除了 AutoCloseable 之外,还(仅)显示了以下 Java 7 库功能

  • ConcurrentModificationException、LinkageError 和 AssertionError 中的异常链接构造函数
  • 基元的静态 .compare() 方法:Boolean.compare(), Byte.compare(), Short.compare(), Character.compare(), Integer.compare(), Long.compare()。
  • Currency: .getAvailableCurrencies(), .getDisplayName() (但没有 .getNumericCode())
  • BitSet: .previousSetBit(), .previousClearBit(), .valueOf(), .toLongArray(), .toByteArray()
  • Collections: .emptyEnumeration(), .emptyIterator(), .emptyListIterator()
  • 自动关闭
  • Throwable:.addSuppressed()、.getSuppressed() 和 4 参数构造函数
  • 字符: .compare(), .isSurrogate(), .getName(), .highSurrogate(), .lowSurrogate(), .isBmpCodePoint() (但没有 .isAlphabetic() 和 .isIdeographic())
  • System: .lineSeparator() (未记录?
  • java.lang.reflect.Modifier: .classModifiers(), .constructorModifiers(), .fieldModifiers(), .interfaceModifiers(), .methodModifiers()
  • NetworkInterface: .getIndex(), .getByIndex()
  • InetSocketAddress: .getHostString()
  • InetAddress: .getLoopbackAddress()
  • Logger: .getGlobal()
  • ConcurrentLinkedDeque
  • 摘要QueuedSynchronizer: .hasQueuedPredecessors()
  • DeflaterOutputStream:带有“syncFlush”的3个构造函数。
  • 降气器: .NO_FLUSH, .SYNC_FLUSH, .FULL_FLUSH, .deflate() 与 4 个参数

基本上就是这样。特别是,NIO 2.0不存在,Arrays.asList仍然没有@SafeVarargs。


答案 2

编辑:在撰写本文时,最新版本是Android 9和Eclipse Indigo。从那时起,事情发生了变化。

  • 实用答案

是的,我试过了。但这不是一个很好的测试,因为兼容性仅限于6级,没有办法(至少没有简单的方法)真正使用java 7:

  • 首先,我在一台没有安装其他JDK的机器上安装了JDK7 - Eclipse和Android也没有安装:

The 7 is the only installed on this machine

  • 然后我安装了一个全新的Eclipse Indigo,并检查它是否真的使用了JDK 7(好吧,因为这是唯一的一个,因为这是我选择的那个,我会感到惊讶)

The 7 is the only used by this Eclipse

  • 然后我安装了最新版本的Android SDK(编辑:Honeycomb,API13,在撰写本文时)。它找到了我的JDK 7并正确安装。ADT 也是如此。

  • 但是当我尝试编译和运行Hello Word Android应用程序时,我感到惊讶。兼容性设置为 Java 6,无法强制其设置为 Java 7:

Compatibility is limited to Java 6

  • 我尝试了一个非Android项目,一个普通的Java项目,我有解释。兼容级别似乎受到 Eclipse 的限制(请参阅下图底部的消息):

Eclipse limits itself to level 6 compatibility

因此,我让Hello World和其他应用程序一起工作,更复杂,使用,和,但这只能证明Java 7的兼容性处理似乎做得很好,并且与Android一起工作。SQLiteListviewSensorCamera

那么,有人尝试过使用好的旧蚂蚁,绕过上面看到的Eclipse限制吗?

  • 理论答案

无论如何,SDK 被设计为与 Java 5 或 6 一起使用,如此所述。

我们可能有一些与Java 7一起工作的东西,但它将是“偶然”工作的。DEX的构建可能正常工作,也可能不工作,一旦DEX构建,它可能会工作或不工作。这是因为根据定义,使用非限定 JDK 会给出不可预测的结果。

即使有人在普通的Java 7下成功地构建了一个Android应用程序,这也不能使JDK合格。应用于另一个应用程序的相同过程可能会失败,或者生成的应用程序可能具有与使用该 JDK 相关的错误。不推荐。

对于那些参与Web应用程序开发的人来说,这与在Java 5或6下部署在仅符合Java 4的应用程序服务器下构建的Web应用程序完全相同(例如,假设Weblogic 8)。这可能有效,但这不是可以推荐用于尝试以外的其他目的。


推荐