当前位置:首页 » 编程软件 » 代码编译框架

代码编译框架

发布时间: 2022-01-11 01:46:59

❶ 如何写一个编译时注解框架

1、注解

我们日常使用的很多开源库都有注解的实现,主要有运行时注解和编译时注解两种。
运行时注解:主要作用就是得到注解的信息
Retrofit:
调用

@GET("/users/{username}")
User getUser(@Path("username") String username);

定义
@Documented
@Target(METHOD)
@Retention(RUNTIME)
@RestMethod("GET")
public @interface GET {
String value();
}

编译时注解:主要作用动态生成代码

Butter Knife

调用
@InjectView(R.id.user)
EditText username;

定义
@Retention(CLASS)
@Target(FIELD)
public @interface InjectView {
int value();
}

2、编译时注解

要实现编译时注解需要3步:

1、定义注解(关于注解的定义可以参考下面引用的博客)
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.ElementType;

@Target({ ElementType.FIELD, ElementType.TYPE })
@Retention(RetentionPolicy.CLASS)
public @interface Seriable
{

}

2、编写注解解析器
@SupportedAnnotationTypes("annotation.Seriable")
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class ViewInjectProcessor extends AbstractProcessor {

@Override
public boolean process(Set annotations,
RoundEnvironment roundEnv) {

for (Element ele : roundEnv.getElementsAnnotatedWith(InjectView.class)) {
if(ele.getKind() == ElementKind.FIELD){
//todo
}

return true;
}

@SupportedAnnotationTypes,定义要支持注解的完整路径,也可以通过getSupportedAnnotationTypes方法来定义
@Override
public Set getSupportedAnnotationTypes() {
Set types = new LinkedHashSet<>();
types.add(InjectView.class.getCanonicalName());

return types;
}

@SupportedSourceVersion(SourceVersion.RELEASE_6)表示支持的jdk的版本
3、创建制定文件resources/META-INF/services/javax.annotation.processing.Processor,并填写注解解析器的类路径,这样在编译的时候就能自动找到解析器

看上去实现编译时注解还是很容易的,但是真要完整的实现一个类似Butter Knife的框架,这还只是开始。
Butter Knife是专注View的注入,在使用注解的类编译后,查看编译后的class文件,会发现多出了文件,如:
SimpleActivity$$ViewInjector.java
SimpleActivity$$ViewInjector.java,就是通过编译时注解动态创建出来的,查看SimpleActivity$$ViewInjector.java的内容
// Generated code from Butter Knife. Do not modify!
package com.example.butterknife;

import android.view.View;

import butterknife.ButterKnife.Finder;

public class SimpleActivity$$ViewInjector {

public static void inject(Finder finder, final com.example.butterknife.SimpleActivity target, Object source) {
View view;
view = finder.findRequiredView(source, 2131230759, "field 'title'");
target.title = (android.widget.TextView) view;
view = finder.findRequiredView(source, 2131230783, "field 'subtitle'");
target.subtitle = (android.widget.TextView) view;
view = finder.findRequiredView(source, 2131230784, "field 'hello', method 'sayHello', and method 'sayGetOffMe'");
target.hello = (android.widget.Button) view;
view.setOnClickListener(
new butterknife.internal.DebouncingOnClickListener() {
@Override
public void doClick(
android.view.View p0
) {
target.sayHello();
}
});
view.setOnLongClickListener(
new android.view.View.OnLongClickListener() {
@Override
public boolean onLongClick(
android.view.View p0
) {
return target.sayGetOffMe();
}
});
view = finder.findRequiredView(source, 2131230785, "field 'listOfThings' and method 'onItemClick'");
target.listOfThings = (android.widget.ListView) view;
((android.widget.AdapterView) view).setOnItemClickListener(
new android.widget.AdapterView.OnItemClickListener() {
@Override
public void onItemClick(
android.widget.AdapterView p0,
android.view.View p1,
int p2,
long p3
) {
target.onItemClick(p2);
}
});
view = finder.findRequiredView(source, 2131230786, "field 'footer'");
target.footer = (android.widget.TextView) view;
}

public static void reset(com.example.butterknife.SimpleActivity target) {
target.title = null;
target.subtitle = null;
target.hello = null;
target.listOfThings = null;
target.footer = null;
}
}

inject方法进行初始化,reset进行释放。inject都是调用Finder的方法与android系统的findViewById等方法很像,再来看Finder类,只截取部分。

public enum Finder {
public T findRequiredView(Object source, int id, String who) {
T view = findOptionalView(source, id, who);
if (view == null) {
String name = getResourceEntryName(source, id);
throw new IllegalStateException("Required view '"
+ name
+ "' with ID "
+ id
+ " for "
+ who
+ " was not found. If this view is optional add '@Nullable' (fields) or '@Optional'"
+ " (methods) annotation.");
}
return view;
}

public T findOptionalView(Object source, int id, String who) {
View view = findView(source, id);
return castView(view, id, who);
}

@Override protected View findView(Object source, int id) {
return ((View) source).findViewById(id);
}

@SuppressWarnings("unchecked") // That's the point.
public T castView(View view, int id, String who) {
try {
return (T) view;
} catch (ClassCastException e) {
if (who == null) {
throw new AssertionError();
}
String name = getResourceEntryName(view, id);
throw new IllegalStateException("View '"
+ name
+ "' with ID "
+ id
+ " for "
+ who
+ " was of the wrong type. See cause for more info.", e);
}
}

findRequiredView方法实际上就是我们常用findViewById的实现,其动态帮我们添加了这些实现。view注入的原理我们就清楚了。
虽然编译时创建了这个类,运行的时候如何使用这个类呢,这里我用自己实现的一个类来描述
public class XlViewInjector {

static final Map, AbstractInjector> INJECTORS = new LinkedHashMap, AbstractInjector>();

public static void inject(Activity activity){
AbstractInjector injector = findInjector(activity);
injector.inject(Finder.ACTIVITY, activity, activity);
}

public static void inject(Object target, View view){
AbstractInjector injector = findInjector(target);
injector.inject(Finder.VIEW, target, view);
}

private static AbstractInjector findInjector(Object target){
Class clazz = target.getClass();
AbstractInjector injector = INJECTORS.get(clazz);
if(injector == null){
try{
Class injectorClazz = Class.forName(clazz.getName()+"$$"+ProxyInfo.PROXY);
injector = (AbstractInjector) injectorClazz.newInstance();
INJECTORS.put(clazz, injector);
}catch(Exception e){
e.printStackTrace();
}
}

return injector;
}
}
XlViewInjector与ButterKnife,比如调用时我们都会执行XlViewInjector.inject方法,通过传入目标类的名称获得封装后的类实例就是SimpleActivity$$ViewInjector.java,再调用它的inject,来初始化各个view。
总结一下整个实现的流程:
1、通过编译时注解动态创建了一个包装类,在这个类中已解析了注解,实现了获取view、设置监听等代码。
2、执行时调用XlViewInjector.inject(object)方法,实例化object类对应的包装类,并执行他的初始化方法inject;
因此我们也能明白为什么XlViewInjector.inject(object)方法一定要在setContentView之后执行。

3、实现注解框架时的坑

解析有用到android api,因此需要创建Android工程,但是android library并没有javax的一些功能,
在eclipse环境下,右键build-path add library把jdk加进来
在android studio下,需要先创建java Library功能,实现与view无关的解析,再创建一个android library功能引用这个工程并实现余下的解析。

❷ 这是C++写的代码框架,这几句怎么理解,为什么模板参数中没有使用class或者typename

定义时模版参数的确可以设置成一个枚举,这样在编译期间就能确定的
而后面的代码是在特例化模版,既然是在特例化,那就可以把枚举值代入了

❸ osgi框架把编译后的代码放在哪里

需配置sqljdbc.jar成runtime依赖 再把sqljdbc.jar一起打包到你的应用程序

❹ 有什么动态编译java源代码的框架

可以的,我说说大概思路,很简单,你自己具体实现吧,把代码写给你没意义的:

  1. 将你这段字符串输出到一个文件里,用Java类文件的方式命名。

  2. 2.调用外部javac命令将该文件编译。

  3. 3.用类加载器(ClassLoad)动态加载新的class文件并用Class.forName()注册该类,然后就可以正常使用了。

  4. 上面的每一步都能在中找到实现方法,自己发挥吧。

❺ ssh框架下实现word在线编译的代码

1-apache的POI,此方法对Excel的导出做的很好,目前对Word的导出方面的功能尚未完全。

2-纯JavaScript脚本实现。主要通过客户端调用本机Office组件来实现。

3-在JSP页面引入头文件实现。

纯JavaScript脚本实现细节方面大体是创建一个word组件ActiveXObject('Word.Application'),用js通过表ID取得表内容然后保存到word,要注意的是js实现有很多不好的地方,例如Internet选项需要把ActiveX空间全部启用,安全级别设置为中。这样的话岂不是每台机器都要配置一下。其次每次生成word文档以后弹出对话框(无法保存此文件,因为它已在别处打开(C:\...\STARTUP\Powerword.dot)),出现此问题就需要把C:\Documents and Settings\当前用户名\Application Data\Microsoft\Word\STARTUP下的Powerword.dot文件删除,每次遇到此问题就需要删除文件来解决,十分不方便。

JSP页面引入来实现Word保存就方便多了,但是也有不足的地方,首先如果需要引入
<meta http-equiv="Content-Type" content="application/msword; charset=gb2312" />

如果需要下载的话就引入

<%@ page contentType="application/msword; charset=gb2312" %>

其实如果大家用框架做就方便多了,比如Struts2。在Action里直接写如下代码:

if(out!=null){
String fileName="";
fileName+="评价报告.doc";
try {
HttpServletResponse response = ServletActionContext.getResponse();
response.setHeader("Content-disposition","attachment; filename="+new String(fileName.getBytes("GB2312"), "8859_1"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}

out是jsp页面表单元素,一个button,用于提交表单到相应Action进行Word下载。Action设置jsp页面头文件。这样每次点击button就可以把相应jsp页面的内容保存到Word中并且支持下载,Word中内容并且是可编辑状态。

不足的地方在于由于表内容是动态生成,有的需要先查看在下载Word,就需要另外建立一个新JSP页面进行Word下载,当然首先要在struts.xml里配置好页面转向。

新建立的页面传值同查看页面要保持一样。

❻ 如何编译CNTK框架

如何编译CNTK框架
现阶段不可能。

.NET 下你用的所有 CLR 方法也好类也好都是封装在一个个 .NET Framework 的 DLL 里的,程序运行时必须这些文件,除非你一个 CLR 类和方法都没用过(那不就是纯 C 语言而且是只有标准库的 C 了么)。

有些类似于 Remote Soft's Salamander .NET Native Compiler、Infralution Globalizer 这些工具,也不是把代码编译成机器语言了,而是把需要的类库等直接写入了 PE,会导致程序体积大大增加,而且只支持 .NET 2.0,最重要的是还是收费软件。

❼ 如何自己编译源代码

我们使用编译器将自己的源代码转换成目标代码, 使用链接器将我们的目标代码链接成一个可执行程序。另外, 我们使用一些程序在计算机中输入源代码文本并且编辑它。这些是最初的和最重要的工具, 它们构成程序员的工具集合或“程序开发环境”。 如果你使用的是命令行窗口, 就像很多专业程序员所做的那样, 你将不得不自己来编写编译和链接命令。如果你使用IDE(“交互式开发环境”或“集成式开发环境”), 就像很多程序员所做的那样, 简单地点击正确按钮就可以完成这个工作。附录C介绍了如何在你的C++实现中编译和链接。 IDE通常包括一个具有有用特性的编辑器, 例如用不同颜色的代码来区分你的源代码中的注释、 关键字和其他部分, 以及其他帮助你来调试代码、 编译和运行代码的功能。调试是发现程序中的错误和排除错误的活动, 你在前进的道路上会听到很多有关它的内容。 我们使用微软的Visual C++作?喑炭 ⒒肪呈道 H绻 颐羌虻サ厮怠氨嘁肫鳌被蚴恰癐DE”的某些部分, 那就是所指Visual C++系统。但是, 你可以使用一些提供最新的、 符合标准的C++实现的系统。我们所说的大多数内容(经过微小的修改)对所有的C++实现都将是正确的, 并且其代码可以在任何地方运行。在工作中, 我们使用几种不同的实现。

源码怎么编译

使用编译器如VC++6.0,VC++2008

❾ 我想让自己的程序(图一)变成图2,怎么使用C++进行编译能不能给出个大概的代码框架结构

图1是字符界面,图2是图形界面,二者差距很大,C++做不出图2的界面来,要用VC++才行。用MFC创建一个单文档工程,就会提供一个开发图形界面的对话框,在对话框里添加控件即可做出图2的界面来;然后为每个控件添加功能代码就基本完成了……

❿ 什么是程序的编辑器,编译器,什么是Framework(框架)

编译器是程序辅助工具,一般会生成一些帮助代码
框架是编程的一种模式,把正个代码实现的功能按起的作用分类,可以使思路清析

热点内容
配置管理由什么组成 发布:2024-12-23 12:57:47 浏览:560
运动版雅阁有哪些配置 发布:2024-12-23 12:57:45 浏览:277
ofp脚本 发布:2024-12-23 12:57:35 浏览:49
服务器地址怎么设置成域名 发布:2024-12-23 12:51:22 浏览:217
理财金额怎么配置 发布:2024-12-23 12:44:18 浏览:69
aspnet文件访问 发布:2024-12-23 12:39:02 浏览:154
搭建邮件服务器的方法 发布:2024-12-23 12:27:27 浏览:430
数据库说明文档 发布:2024-12-23 12:22:12 浏览:620
安卓手机玩mc卡怎么办 发布:2024-12-23 12:15:46 浏览:5
mt编译时出现错误信息 发布:2024-12-23 12:15:45 浏览:107