码迷,mamicode.com
首页 > 编程语言 > 详细

关于java编译时注解你需要知道的二三事。解除你的顾虑!

时间:2016-05-05 22:43:56      阅读:3303      评论:0      收藏:0      [点我收藏+]

标签:

转载请注明出处:
http://blog.csdn.net/liu470368500/article/details/51316066

做Android开发。大家肯定会关心你的app的性能问题。不知道从何时开始。网上有流传一句。不要使用注解。用注解会影响性能。这不能说错。但是也不能说对。这里普及一下关于注解的一些你需要知道的知识

网上常说的注解。基本是运行时注解。而所说的注解会影响性能。则是指的此类型的注解。因为运行时注解的解析。完全依赖于反射。而反射的效率。是比原生的慢的。特别是对于原先的老机型。本来配置就低。运行就卡。再使用过多注解。运行时去反射解析。就导致运行效率更慢了。这也就是网上老司机们所说的。注解会影响性能的主因了。但是其实这个基本可以不用去管。现在的手机运行得那么溜。你就是用注解。那其实也影响不了多少性能的。

而对于编译时注解。就不一样了。我们都知道。我们写的java文件。会先经过编译。将java文件编译成.class文件。再对class文件进行打包等一系列处理。生成apk。最终才运行到我们的手机上。所以编译时注解。是在java编译生成.class文件这一步进行的操作。根本和我们的apk运行。没半毛钱关系。所以效率问题也就无从说起了。

区分注解使用的是运行时。还是编译时。我们只需要看注解的定义就行。如:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
public @interface Params {
    ...
}
@Inherited
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Field {
    ...
}

@Retention是一种元注解。指定该注解的作用域。RUNTIME则是指的运行时注解。CLASS则是指的编译时注解。还有一种叫做SOURCE。基本很难用到。此处就不说了。

编译时注解对比运行时注解的优势在于。它是在对程序进行编译时期。根据你的注解处理器的逻辑。处理该注解。并生成相应的java文件。提供给你调用。所以。使用编译时注解。你程序运行时。是使用的生成的普通java类来提供调用。而不是像运行时注解那样通过反射来调用。程序性能问题也就无从说起了。

下面来说一个对于编译时注解。需要注意的问题。

我们都知道。在Android上的程序。有个64K的方法数限制。当然。网上也有说是64K的类数限制。具体是方法数还是类数咱不去管。但是肯定是有限制。所以。现在很多人对于引进一个库。有个衡量的标准。就是看jar包的大小。方法数有多少。来衡量是否引进该lib。其实在此我想说。对于一般的库你这样来衡量无可厚非。但是编译时注解的库。就需要用另一种眼光来看了。

下面我先来说说对于编译时注解框架引入项目的方式。对于Android Studio来说。这玩意引入很简单。

首先。在项目根目录的build.gradle中。加入apt框架

classpath ‘com.neenbedankt.gradle.plugins:android-apt:1.4‘

然后。在要使用编译时注解框架的module中。应用apt插件。加入编译时注解框架引用

apply plugin: ‘com.neenbedankt.android-apt‘
dependencies {
    compile ‘org.lzh.compiler.lib:processortool-api:0.6‘
    apt ‘org.lzh.compiler.lib:processortool-compiler:0.6‘
}

compile 命令引用的是编译时注解框架的api。即项目中需要使用的注解。都是来自于这种库。
apt 命令是引用的编译时注解框架的注解处理器lib。在程序编译时。会调用该库中的注解处理器去进行注解处理。生成符合逻辑的java文件提供调用。

下面是Eclipse的用法。还是以上面的框架为例。

框架分为api和compiler两部分。在项目上libs文件夹下。放置api的lib。
技术分享

然后需要配置使用的注解处理器部分。光标放项目名上点击ALT + ENTER进入Properties找到Java compiler:
技术分享

1处打开注解处理器开关。2处指定生成的java文件所放置的路径。
技术分享

1处激活配置。2处添加处理处理器的jar包以及该注解处理器依赖的jar包。apply应用即可。这样就配置完全了Eclipse下添加编译时注解框架的流程。

然后注解处理器既然是生成了java类文件。那么就肯定需要我们自己能够查阅该生成的文件。对于Andorid Studio工程。生成的代码类的位置位于build文件夹下:
技术分享

图中圈出来的即是生成的java类代码。根据使用的apt的版本不同。路径也有所不同。此处生成于build/generated/source/apt目录下。也有别的apt版本。生成的类位于build/source文件夹下。就这两个地址。找找就知道了。

然后对于Eclipse工程。还记得Eclipse图配置的第一张图的第2处吧。有个.apt_generated的路径名。生成的文件就位于这个路径下:
技术分享

好了。学会配置之后。再来说上面提到的问题。为什么说对于编译时注解的库。我们需要用另一种眼光来判断是否可以引进入项目中呢。

因为我们项目引进的其实只有api的lib。对于注解处理器的lib。那是提供给IDE使用的。并不会将compiler的jar打包到你的APK中去。所以看引入后方法量的增加数量。一个就是看api的lib所含有的方法数。一个就是被编译处理之后。生成的代码数。这就是和一般的lib不一样的地方。

来做个证明。
技术分享

图中的两个jar包即是编译时注解框架的两个lib。两个apk。app-debug-apt.apk为引入了该框架的。app-debug-noapt.apk为没有引用该框架的。从他们的大小就可以看出。打包时肯定没有将compiler的jar包给打包进入 apk中。

当然。还有一种方式可以证明。即你在项目中使用的时候。你是完全不可以拿到compiler中的类。只能拿到api中所存在的类。并使用它。这个有兴趣的也可以试试。

如果有对于编译时注解感兴趣的童鞋,推荐几个网址以供学习:

这篇文章主要是讲对于处理器开发的具体使用逻辑。以及应该注意的地方。
http://www.importnew.com/15246.html
这篇文章主要是讲对于处理器开发的模式。比如分为api与compiler以及遇到一些问题的解决方案
http://brianattwell.com/android-annotation-processing-pojo-string-generator/

关于java编译时注解你需要知道的二三事。解除你的顾虑!

标签:

原文地址:http://blog.csdn.net/liu470368500/article/details/51316066

(1)
(2)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!