精华内容
下载资源
问答
  • 如果手写不仅每次都要修改代码,还要每次测试版,而且无法灵活根据用户定义的规则动态处理逻辑。所以想到将公共逻辑写到父类实现,将特定逻辑根据字符串动态生成子类处理。这就可以一劳永逸解决这个问题。那就着手...

    最近一个项目中利用规则引擎,提供用户拖拽式的灵活定义规则。这就要求根据数据库数据动态生成对象处理特定规则的逻辑。如果手写不仅每次都要修改代码,还要每次测试发版,而且无法灵活根据用户定义的规则动态处理逻辑。所以想到将公共逻辑写到父类实现,将特定逻辑根据字符串动态生成子类处理。这就可以一劳永逸解决这个问题。

    那就着手从Java如何根据字符串模板在运行时动态生成对象。

    Java是一门静态语言,通常,我们需要的class在编译的时候就已经生成了,为什么有时候我们还想在运行时动态生成class呢?

    经过一番网上资料查找,由繁到简的方式总结如下:

    一、利用JDK自带工具类实现

    现在问题来了,动态生成字节码,难度有多大?

    如果我们要自己直接输出二进制格式的字节码,在完成这个任务前,必须先认真阅读JVM规范第4章,详细了解class文件结构。估计读完规范后,两个月过去了。

    所以,第一种方法,自己动手,从零开始创建字节码,理论上可行,实际上很难。

    第二种方法,使用已有的一些能操作字节码的库,帮助我们创建class。

    目前,能够操作字节码的开源库主要有CGLib和Javassist两种,它们都提供了比较高级的API来操作字节码,最后输出为class文件。

    比如CGLib,典型的用法如下:

    Enhancer e = newEnhancer();

    e.setSuperclass(...);

    e.setStrategy(newDefaultGeneratorStrategy() {protectedClassGenerator transform(ClassGenerator cg) {return newTransformingGenerator(cg,new AddPropertyTransformer(new String[]{ "foo"},newClass[] { Integer.TYPE }));

    }});

    Object obj= e.create();

    比自己生成class要简单,但是,要学会它的API还是得花大量的时间,并且,上面的代码很难看懂对不对?

    有木有更简单的方法?

    有!

    Java的编译器是javac,但是,在很早很早的时候,Java的编译器就已经用纯Java重写了,自己能编译自己,行业黑话叫“自举”。从Java 1.6开始,编译器接口正式放到JDK的公开API中,于是,我们不需要创建新的进程来调用javac,而是直接使用编译器API来编译源码。

    使用起来也很简单:

    JavaCompiler compiler =ToolProvider.getSystemJavaCompiler();int compilationResult = compiler.run(null, null, null, '/path/Test.java');

    这么写编译是没啥问题,问题是我们在内存中创建了Java代码后,必须先写到文件,再编译,最后还要手动读取class文件内容并用一个ClassLoader加载。

    有木有更简单的方法?

    有!

    其实Java编译器根本不关心源码的内容是从哪来的,你给它一个String当作源码,它就可以输出byte[]作为class的内容。

    所以,我们需要参考Java Compiler API的文档,让Compiler直接在内存中完成编译,输出的class内容就是byte[]。

    Mapresults;

    JavaCompiler compiler=ToolProvider.getSystemJavaCompiler();

    StandardJavaFileManager stdManager= compiler.getStandardFileManager(null, null, null);try (MemoryJavaFileManager manager = newMemoryJavaFileManager(stdManager)) {

    JavaFileObject javaFileObject=manager.makeStringSource(fileName, source);

    CompilationTask task= compiler.getTask(null, manager, null, null, null, Arrays.asList(javaFileObject));if(task.call()) {

    results=manager.getClassBytes();

    }

    }

    上述代码的几个关键在于:

    用MemoryJavaFileManager替换JDK默认的StandardJavaFileManager,以便在编译器请求源码内容时,不是从文件读取,而是直接返回String;

    用MemoryOutputJavaFileObject替换JDK默认的SimpleJavaFileObject,以便在接收到编译器生成的byte[]内容时,不写入class文件,而是直接保存在内存中。

    最后,编译的结果放在Map中,Key是类名,对应的byte[]是class的二进制内容。

    为什么编译后不是一个byte[]呢?

    因为一个.java的源文件编译后可能有多个.class文件!只要包含了静态类、匿名类等,编译出的class肯定多于一个。

    如何加载编译后的class呢?

    加载class相对而言就容易多了,我们只需要创建一个ClassLoader,覆写findClass()方法:

    class MemoryClassLoader extendsURLClassLoader {

    Map classBytes = new HashMap();public MemoryClassLoader(MapclassBytes) {super(new URL[0], MemoryClassLoader.class.getClassLoader());this.classBytes.putAll(classBytes);

    }

    @Overrideprotected Class> findClass(String name) throwsClassNotFoundException {byte[] buf =classBytes.get(name);if (buf == null) {return super.findClass(name);

    }

    classBytes.remove(name);return defineClass(name, buf, 0, buf.length);

    }

    }

    总结以上,那么我们来编写一个Java脚本引擎吧:

    二、利用三方Jar包实现

    利用三方包com.itranswarp.compiler来实现:

    1. 引入Maven依赖包:

    com.itranswarp

    compiler

    1.0

    2. 编写工具类

    public classStringCompiler {public static Object run(String source, String...args) throwsException {//声明类名

    String className = "Main";

    String packageName= "top.fomeiherz";//声明包名:package top.fomeiherz;

    String prefix = String.format("package %s;", packageName);//全类名:top.fomeiherz.Main

    String fullName = String.format("%s.%s", packageName, className);//编译器

    JavaStringCompiler compiler = newJavaStringCompiler();//编译:compiler.compile("Main.java", source)

    Map results = compiler.compile(className + ".java", prefix +source);//加载内存中byte到Class>对象

    Class> clazz =compiler.loadClass(fullName, results);//创建实例

    Object instance =clazz.newInstance();

    Method mainMethod= clazz.getMethod("main", String[].class);//String[]数组时必须使用Object[]封装//否则会报错:java.lang.IllegalArgumentException: wrong number of arguments

    return mainMethod.invoke(instance, newObject[]{args});

    }

    }

    3. 测试执行

    public classStringCompilerTest {public static void main(String[] args) throwsException {//传入String类型的代码

    String source = "import java.util.Arrays;public class Main" +

    "{" +

    "public static void main(String[] args) {" +

    "System.out.println(Arrays.toString(args));" +

    "}" +

    "}";

    StringCompiler.run(source,"1", "2");

    }

    }

    三、利用Groovy脚本实现

    以上两种方式尝试过,后来发现Groovy原生就支持脚本动态生成对象。

    1. 引入Groovy maven依赖

    org.codehaus.groovy

    groovy-all

    2.4.13

    2. 直接上测试代码

    @Testpublic void testGroovyClasses() throwsException {//groovy提供了一种将字符串文本代码直接转换成Java Class对象的功能

    GroovyClassLoader groovyClassLoader = newGroovyClassLoader();//里面的文本是Java代码,但是我们可以看到这是一个字符串我们可以直接生成对应的Class>对象,而不需要我们写一个.java文件

    Class> clazz = groovyClassLoader.parseClass("package com.xxl.job.core.glue;\n" +

    "\n" +

    "public class Main {\n" +

    "\n" +

    " public int age = 22;\n" +

    " \n" +

    " public void sayHello() {\n" +

    " System.out.println(\"年龄是:\" + age);\n" +

    " }\n" +

    "}\n");

    Object obj=clazz.newInstance();

    Method method= clazz.getDeclaredMethod("sayHello");

    method.invoke(obj);

    Object val=method.getDefaultValue();

    System.out.println(val);

    }

    展开全文
  • /** 搜索按钮操作 */ handleQuery() { //获取下拉选择搜索的类型和输入的值 console.log(this.queryMsg); console.log(this.select); var params = { enterpriseid: "5", groupid: this.groupId, ...
      /** 搜索按钮操作 */
        handleQuery() {
          //获取下拉选择搜索的类型和输入的值
          console.log(this.queryMsg);
          console.log(this.select);
          var params = {
            enterpriseid: "5",
            groupid: this.groupId,
            groups: this.groupId,
          };
          //这句是重点, this.queryMsg  这个是我的变动参数字段,可以是user,也可以是password
          //this.select这个是具体的输入值
         this.$set(params,this.select,this.queryMsg)
     
          this.getList(params);
        },
    
    展开全文
  • 摘要:消灭能够关系更和引起、对象的编变劳动产生法律,后果具有一定的活动法律,志为转移以当的意是指事人。对象的编缓刑战时件包用条的适括(。信息人应内容证两种文披露义务一致本的当保,程语同时外文文本的采用...

    favicon_example.jpg摘要:

    消灭能够关系更和引起、对象的编变劳动产生法律,后果具有一定的活动法律,志为转移以当的意是指事人。对象的编缓刑战时件包用条的适括(。信息人应内容证两种文披露义务一致本的当保,程语同时外文文本的采用,准以外本为文文,歧义文本两种发生时。...

    消灭能够关系更和引起、对象的编变劳动产生法律,后果具有一定的活动法律,志为转移以当的意是指事人。

    人按纳税照规寄方取邮报纳定采式申税的,程语)日日期以(期为实际申报。

    对象的编缓刑战时件包用条的适括(。胸段正常脊髓,脑脊液无色,后发1天展至肢无力双上,性患者某女,增粗I检:颈查示髓略,正常压力,白细胞4,信号异常未见,质0蛋白,肢肌级力2双下。险条件具备一定的危,危险称为可保。下列选项中,选择协议关于正确路由的说的是法不。

    38005.jpg

    信息人应内容证两种文披露义务一致本的当保,程语同时外文文本的采用,准以外本为文文,歧义文本两种发生时。下列选项中,叙述关于静态确的表的不正路由是(。

    应(,对象的编需作规格品种筋的、级别或变更当钢时。护时盖浇)天间不于(其覆得少水养,程语凝土通混渣硅用矿拌制对采的普酸盐水泥。根据规定,对象的编主要缴纳有(方式税款。程语下列选项国优中属作中于我优待对象的是抚工。小钱后接退役置办安置受安,对象的编何能他觉己没有任力得自,针对这种情况,先要员首安置办人,,作也趣了兴对工失去。

    程语下列工作作方中的目标于社用于优抚安置区工不属法运社会是(。性肿黑痣为良物,对象的编为可分。

    程语现是人最破伤初表风病。

    男性,对象的编年左背部肿物2,肿物压迫叶状呈分,不痛,查体,考虑。

    学专格考题集最严重的治医症是业主并发外科师资试习,程语养中胃肠外营的全长期。

    对象的编下列性缺哪项高渗诊断依据不是水的。夏季行走在田间小傍晚路上,女性,突然足背咬伤被蛇,,岁。,下正常情况。程语现是人最破伤初表风病。

    展开全文
  • 在Visual Basic中,常用的数据访问接口有下列三种:数据库访问对象(DAO,Data Access Object)、远程数据库对象(RDO,Remote Data Object)和ActiveX数据对象(ADO,ActiveX Data Object )。数据库访问技术一直在不断...

    在Visual Basic中,常用的数据访问接口有下列三种:数据库访问对象(DAO,Data Access Object)、远程数据库对象(RDO,Remote Data Object)和ActiveX数据对象(ADO,ActiveX Data Object )。数据库访问技术一直在不断进步,而这三种接口的每一种都分别代表了该技术的不同发展阶段。最新的是ADO,它是比RDO和DAO更加简单,然而更加灵活的对象模型。正因如此,越来越多的人在用VB开发数据库软件时使用ADO作为数据访问接口。在开发过程中,我们通常的使用的方法是:先使用数据库管理系统(例如:Microsoft Access)或VB中的可视化数据管理器建立好数据库和数据表结构,然后在程序中通过使用ADODC数据库控件或引用ADO对象与数据库中的表建立连接,再通过数据库感知控件(例如:文本框、DataGrid等)来进行数据库的各种操作。在这种开发过程中,我们有时需要面对这样一个问题:如何让用户在程序运行过程中动态地建立自己所需的数据库和数据表以提高程序的灵活性呢?在程序运行过程中建立自己所需的数据库和数据表,其本质就是用代码(或者说通过编程)来建立数据库和数据表。众所周知,在Foxpro或ASP编程中,这是很容易的一件事件。那么在VB数据库编程中又是怎样来操作的呢?在VB数据库编程中,如果使用DAO作为数据库访问接口技术,则可以用CreateDatabase结合CreateTableDef方法来实现,目前已有不少书和杂志都讲到了这种方法,本文就不再讲述了;但你如果使用的是最新的数据库访问接口技术ADO,你却发现目前的书和杂志上没有文章讲到如何用代码来建立数据库和数据表的方法,可有时我们非常需要用到这种方法,下面我们就来解决这个问题

    2: ADO与ADOX

    我们先来对ADO 和ADOX进行简单的认识。在VB6中,使用ADO开发数据库应用程序时,我们要引用对象库"Microsoft ActiveX Data Objects 2.5 Library", 这个东西的简称就是ADO,它是VB6数据库最核心的对象群,也是VB数据库开发人员经常所引用的对象库,在VB6中你可以看到它的各种版本,从2.0版到2.6版都有,很多人对它已经很熟悉,在此我们不再详细介绍。如果要在程序运行过程中创建数据库和表,我们还要引用对象库"Microsoft ADO Ext 2.1. For DDL Security",简称为ADOX,其库文件名为是:Msadox.dll。ADOX是对 ADO 对象和编程模型的扩展,它将 ADO 扩展为包括创建、修改和删除模式对象,如表格和过程。它还包括安全对象,用于维护用户和组,以及授予和撤消对象的权限。ADOX的对象如下表所示

    对象 说明

    Catalog 包含描述数据源模式目录的集合。

    Column 表示表、索引或关键字的列。

    Group  表示在安全数据库内有访问权限的组帐号。

    Index  表示数据库表中的索引。

    Key  表示数据库表中的主关键字、外部关键字或唯一关键字。

    Procedure 表示存储的过程。

    Table  表示数据库表,包括列、索引和关键字。

    User  表示在安全数据库内具有访问权限的用户帐号。

    View  表示记录或虚拟表的过滤集。

    ADOX常用方法有:Append(包括Columns、Groups、Indexes、Keys、Procedures、Tables、Users、Views)、Create(创建新的目录)、Delete(删除集合中的对象)、Refresh(更新集合中的对象)等等。有关 ADOX 的详细信息,请在 http://www.microsoft.com/data/ado 中参阅 Microsoft 发布的有关 ADOX说明的 Web 页。

    3: 在原有数据表的基础上产生新的数据表

    如果仅仅是在已有的数据表的基础上产生新的数据表,我们只要引用对象库"Microsoft ActiveX Data Objects 2.5 Library"再利用Select…Into语句就可以了。例如:有一个名为Wage.mdb的数据库,数据库中有一个名为"工资表"数据表,该数据表的字段有:编号、姓名、基本工资、津贴、应发工资、扣款、实发工资等,这个表中已经有很多的记录。现在我们把其中的实发工资大于2000的记录筛选出来组成一个新表,新表的名称由用户从文本框中输入,新表中我们只要三个字段,它们是:编号、姓名、实发工资。我们用下列程序就可以实现:

    (事先在窗体中添加一个文本框Text1和一个命令按钮Command1)

    Dim conn As New ADODB.Connection

    Dim rs As New ADODB.Recordset

    Dim command As New ADODB.command

    Private Sub Command1_Click()

    Dim bm As String

    Dim sql As String

    If Text1.Text <>"" Then

    bm = Trim(Text1.Text)

    sql= "Select 编号,姓名,实发工资 Into " + bm + " From 工资表 Where 实发工资>2000"

    Set command.ActiveConnection = conn

    command.CommandText = sql

    command.Execute

    Else

    MsgBox "你必须输入一个名字"

    End If

    Private Sub Form_Load()

    Dim str As String

    str = App.Path

    If Right(str, 1) <>"\" Then

    str = str + "\"

    End If

    pstr = "Provider=Microsoft.Jet.OLEDB.3.51;"

    pstr = pstr & "Persist Security Info=False;"

    pstr = pstr & "Data Source=" & str & "wage.mdb"

    conn.Open pstr

    rs.CursorLocation = adUseClient

    rs.Open "工资表", conn, adOpenKeyset, adLockPessimistic

    Set DataGrid1.DataSource = rs

    End Sub

    当然,我们还可以把程序设计得更好,比如:让用户先在窗口中任意选择所需的字段和一些条件,然后再组合生成一个新表。但无论如何,这种操作只能在从原表的基础上产生一个新表,不能产生一个数据库文件,并且新表和原表放在同一个数据库中。

    展开全文
  • 示例代码:show()方法是动态多态的体现,参数为父类对象,instanof运算符判断某对象是否是类的实例,然后转换为下转型对象调用子类新增的方法。public class TestAnimalDemo {public static void main(String[] arg....
  • 上一期是变量,在java中变量总是无处不在,而变量其意就是可以改变的数,在一般情况下我们可以以变量类型,变量名,变量值来描述它这一期是给面向对象(OOP)开了一个头,对他的概念,三大特征有了一个基础的认识,...
  • SpringAOP 1.X中增强类的实现及织入创建动态代理的对象过程一、增强实现类织入动态代理类的结构图二、创建目标对象(被代理对象)接口及实现目标对象接口(一) 创建目标对象接口(二) 实现目标对象接口三、实现...
  • 动态绑定(二)面向对象分析1. 认定对象2. 组织对象3. 对象间的相互作用4. 基于对象的操作(三)面向对象设计1. 面向对象设计的活动2. 面向对象设计原则(四)面向对象程序设计1. 类2. 继承和类层次结构3. 对象、...
  • 今天,芝麻科技讯小编再分享一个新的微信表白技巧,可以在聊天界面,看到满屏的动态爱心效果,个性又浪漫,下面先来看下效果。怎么样?是不是很个性呢?单身族用来表白,又或者是情人节发给Ta的话,相信会很不错。...
  • 计算机核心期刊哪些好发布时间:2016-05-17 16:53所属分类:期刊百科发表计算机核心论文可以选择哪些期刊,发表计算机核心论文有可能评职称的需要或者是毕业的需要,但无论是那种情况发表论文都需要注意是不是有效...
  • response对象主要用于对客户端的请求进行回应,将web服务器处理后的结果回给客户端,封装了jsp产生的响应,并发送到客户端响应客户端的请求,请求的数据可以是各种数据类型,甚至是文件。 常用的方法:void add...
  • 虽然Precomputed Realtime Gl不支持区域光源(Area Light),但是可以使用“Emissive...“发射(Emission)”是一个标准着色器的属性,允许场景中的静态对象发光。但是默认“Emisson”的值是0。这意味着使用标准着色器的...
  • 教改类文章在期刊上发表论文的时候要选择合适的期刊来发表,那么教改类文章容易的核心期刊有哪些,阿狸老师通过第八版中文核心目录整理了3本教改类核心刊物:《教育学报》、《课程.教材.教供》、《教育理论与实践...
  • java定义一个对象数组

    2021-04-10 10:50:12
    java怎么定义一个动态数组,Java初学者入门应该掌握的30个概念,java定义一个对象数组,java一维数组定义摘要: java 是面向对象程序设计语言, 对象数组作为 javase 中的基础...Java 中数组的声明一维数组的声明: 在 ...
  • 我是懒得去准备数据库 而且成员名称要么与网页上要显示的数据对应,要么与数据库查询结果的字段相对应, 每次开发的时候创建实体类都是一堆,三五个都算少的,还要加getter setter方法等, 然后今天突然想点什么...
  • Python面向对象编程

    2021-04-27 03:18:38
    面向对象的程序设计把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递。在Python中,所有数据类型都可以视为对象,...
  • python面向对象编程

    2021-08-14 10:26:15
    下次遇到有人这样问,你就可以直接回答他,谁都有对象,因为一切皆为对象。 我们之前的编程都是指令式编程,即输入指令一条一条的执行,程序简单时没有任何问题,但是随着问题复杂性的增加,指令式编程将会明显不能...
  • 当前位置:我的异常网» Ajax»,请教用ajax如何传对象呢? 能不能传对象,请教用ajax如何传对象呢? 能不能传对象www.myexceptions.net网友分享于:2015-08-26浏览:80次各位高手,请问用ajax怎么传对象呢? 能不能...
  • 为了对对象进行初始化,c++提供了构造函数来处理对象的初始化,构造函数是一种特殊的成员函数,与其他函数不同,构造函数时在建立对象时自动执行。 构造函数的作用:对象的初始化 构造函数的调用:由编译器自动调用 ...
  • 对象动态属性写法,[],中括号获取对象属性,[method.toLowerCase() === 'get' ? 'params' : 'data']: submitData
  • 面向对象方法学引论9.1 面向对象方法学概述9.1.1 面向对象方法学的要点9.1.2 面向对象方法学的优点9.2 面向对象概念9.2.1 对象9.2.2 其他概念9.3 面向对象建模9.4 对象模型9.4.1 类图的基本符号9.4.2 表示关系的符号...
  • 这两者最大的区别在于基于 JDK 的动态代理需要被代理的对象有接口,而基于 Cglib 的动态代理并不需要被代理对象有接口。 那么小伙伴们不禁要问,Spring 中的 AOP 是怎么实现的?是基于 JDK 的动态
  • 我们主要讲一下php面向对象的一些用法与实例教程例子等哦,开始我们只讲一下面向对象的概念与php的简单例子教程哦。第七章(1)面向对象详解_面向对象的概念什么是类:...什么是成员方法:定义成员动态描述.能实现一些什...
  • Java运行时动态生成类几种方式

    千次阅读 2021-02-12 10:23:51
    如果手写不仅每次都要修改代码,还要每次测试版,而且无法灵活根据用户定义的规则动态处理逻辑。所以想到将公共逻辑写到父类实现,将特定逻辑根据字符串动态生成子类处理。这就可以一劳永逸解决这个问题。那就着手...
  • 其中: Component定义一个对象接口,可以给这些对象动态地添加职责 ConcreteComponent定义一个对象,可以给这个对象添加一些职责 Decorator维持一个指向Component对象的指针,并定义一个与Component接口一致的接口 ...
  • 静态代理,JDK动态代理,Cglib动态代理详解

    千次阅读 热门讨论 2021-02-12 13:21:39
    关注微信公众号【Java之言】,...代理类与委托类之间通常会存在关联关系,一个代理类对象与一个委托类对象(目标对象)关联,代理类对象本身并不真正实现服务,而是通过调用委托类对象的相关方法,来提供特定的服务。 .
  • 面向对象设计与分析

    2021-01-12 14:16:58
    抽象 abstract 舍弃个别非本质的特征。...对象客观事物分类:物理实体(飞机)、人或组织的角色(医生)、应该记忆的事件(飞行)、两个或多个对象的相互作用(购买)、需要说明的概念(政策)。 一组相似对象的定
  • 做流程图的项目时,新的流程定义为xml的,需要对xml与java对象进行互转查了一下activiti的转换xml方式,发现转换太麻烦了,需要一步步的解析xml后面发现直接用jaxb就可以很快实现互转,而且现在这个jaxb在jdk内,不...
  • 如果反质量为零,我们认为它是不可移动的,请在其附加对象(例如头部)之后更新其位置,然后跳过这些粒子的其余步骤。 我们为顶点0和1分配了零个逆质量,这样它们就可以随着头部移动而设置动画。 约束 有三种约束。...
  • 这个坑其实在社区已经有人解答,只是在“问答”中不易被公众...我发现很多人都懒得点赞),所以建议Michael、小木老师整一个文人自己选出最佳答案的功能正题正题:由于小程序不支持DOM操作,也就没有了获取文档对象...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 169,251
精华内容 67,700
关键字:

发对象的动态应该怎么发