使用JavaSymbolSolver解决Java代码中的方法调用

为什么创建java-symbol-solver?

几年前,我开始使用JavaParser ,然后开始做出贡献。 不久之后,我意识到我们想对Java代码执行的许多操作不能仅通过使用解析器生成的抽象语法树来完成,我们还需要解析类型,符号和方法调用。 因此,我创建了JavaSymbolSolver 。 现在, Coati已将其用于生产静态分析工具。

缺少的一件事是文档:人们在JavaParser上打开问题,询问如何回答某个问题,而答案通常是“为此,您需要使用JavaSymbolSolver”。 从这些问题开始,我将展示一些示例。

受此问题的启发,我将展示如何生成对特定方法的所有调用的列表。

我们如何使用java-symbol-solver解决Java中的方法调用?

可以分两步完成:

  1. 您在源代码上使用JavaParser来构建AST
  2. 您在表示方法调用的AST的节点上调用JavaSymbolSolver并获得答案

我们将写一个简短的例子。 最后,我们将得到一个应用程序,给定源文件将产生以下结果:

* L55 setId(id)   -&qt; com.github.javaparser.ast.body.VariableDeclarator.setId(com.github.javaparser.ast.body.VariableDeclaratorId)* L59 setId(new VariableDeclaratorId(variableName))   -&qt; com.github.javaparser.ast.body.VariableDeclarator.setId(com.github.javaparser.ast.body.VariableDeclaratorId)* L71 setId(id)   -&qt; com.github.javaparser.ast.body.VariableDeclarator.setId(com.github.javaparser.ast.body.VariableDeclaratorId)* L72 setInit(init)   -&qt; com.github.javaparser.ast.body.VariableDeclarator.setInit(com.github.javaparser.ast.expr.Expression)* L76 setId(new VariableDeclaratorId(variableName))   -&qt; com.github.javaparser.ast.body.VariableDeclarator.setId(com.github.javaparser.ast.body.VariableDeclaratorId)* L77 setInit(init)   -&qt; com.github.javaparser.ast.body.VariableDeclarator.setInit(com.github.javaparser.ast.expr.Expression)* L82 setId(id)   -&qt; com.github.javaparser.ast.body.VariableDeclarator.setId(com.github.javaparser.ast.body.VariableDeclaratorId)* L83 setInit(init)   -&qt; com.github.javaparser.ast.body.VariableDeclarator.setInit(com.github.javaparser.ast.expr.Expression)* L88 v.visit(this, arg)   -&qt; com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.body.VariableDeclarator, A)* L93 v.visit(this, arg)   -&qt; com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.body.VariableDeclarator, A)* L106 setAsParentNodeOf(this.id)   -&qt; com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)* L112 setAsParentNodeOf(this.init)   -&qt; com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)* L121 setAsParentNodeOf(this.init)   -&qt; com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)* L128 getParentNodeOfType(NodeWithElementType.class)   -&qt; com.github.javaparser.ast.Node.getParentNodeOfType(java.lang.Class<T&qt;)* L130 wrapInArrayTypes(elementType.getElementType(), elementType.getArrayBracketPairsAfterElementType(), getId().getArrayBracketPairsAfterId())   -&qt; com.github.javaparser.ast.type.ArrayType.wrapInArrayTypes(com.github.javaparser.ast.type.Type, java.util.List<com.github.javaparser.ast.ArrayBracketPair&qt;...)* L130 elementType.getElementType()   -&qt; com.github.javaparser.ast.nodeTypes.NodeWithElementType.getElementType()* L131 elementType.getArrayBracketPairsAfterElementType()   -&qt; com.github.javaparser.ast.nodeTypes.NodeWithElementType.getArrayBracketPairsAfterElementType()* L132 getId().getArrayBracketPairsAfterId()   -&qt; com.github.javaparser.ast.body.VariableDeclaratorId.getArrayBracketPairsAfterId()* L132 getId()   -&qt; com.github.javaparser.ast.body.VariableDeclarator.getId()* L137 ArrayType.unwrapArrayTypes(type)   -&qt; com.github.javaparser.ast.type.ArrayType.unwrapArrayTypes(com.github.javaparser.ast.type.Type)* L138 getParentNodeOfType(NodeWithElementType.class)   -&qt; com.github.javaparser.ast.Node.getParentNodeOfType(java.lang.Class<T&qt;)* L142 nodeWithElementType.setElementType(unwrapped.a)   -&qt; com.github.javaparser.ast.nodeTypes.NodeWithElementType.setElementType(com.github.javaparser.ast.type.Type<?&qt;)* L143 nodeWithElementType.setArrayBracketPairsAfterElementType(null)   -&qt; com.github.javaparser.ast.nodeTypes.NodeWithElementType.setArrayBracketPairsAfterElementType(java.util.List<com.github.javaparser.ast.ArrayBracketPair&qt;)* L144 getId().setArrayBracketPairsAfterId(unwrapped.b)   -&qt; com.github.javaparser.ast.body.VariableDeclaratorId.setArrayBracketPairsAfterId(java.util.List<com.github.javaparser.ast.ArrayBracketPair&qt;)* L144 getId()   -&qt; com.github.javaparser.ast.body.VariableDeclarator.getId()

在此源文件上执行时:

/** Copyright (C) 2007-2010 J?lio Vilmar Gesser.* Copyright (C) 2011, 2013-2016 The JavaParser Team.** This file is part of JavaParser.* * JavaParser can be used either under the terms of* a) the GNU Lesser General Public License as published by*     the Free Software Foundation, either version 3 of the License, or*     (at your option) any later version.* b) the terms of the Apache License ** You should have received a copy of both licenses in LICENCE.LGPL and* LICENCE.APACHE. Please refer to those files for details.** JavaParser is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the* GNU Lesser General Public License for more details.*/package com.github.javaparser.ast.body;import com.github.javaparser.Range;
import com.github.javaparser.ast.ArrayBracketPair;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.NameExpr;
import com.github.javaparser.ast.nodeTypes.NodeWithElementType;
import com.github.javaparser.ast.nodeTypes.NodeWithType;
import com.github.javaparser.ast.type.ArrayType;
import com.github.javaparser.ast.type.Type;
import com.github.javaparser.ast.visitor.GenericVisitor;
import com.github.javaparser.ast.visitor.VoidVisitor;
import com.github.javaparser.utils.Pair;import java.util.List;import static com.github.javaparser.ast.type.ArrayType.wrapInArrayTypes;/*** @author Julio Vilmar Gesser*/
public final class VariableDeclarator extends Node implementsNodeWithType<VariableDeclarator&qt; {private VariableDeclaratorId id;private Expression init;public VariableDeclarator() {}public VariableDeclarator(VariableDeclaratorId id) {setId(id);}public VariableDeclarator(String variableName) {setId(new VariableDeclaratorId(variableName));}/*** Defines the declaration of a variable.* * @param id The identifier for this variable. IE. The variables name.* @param init What this variable should be initialized to.*            An {@link com.github.javaparser.ast.expr.AssignExpr} is unnecessary as the <code&qt;=</code&qt; operator is*            already added.*/public VariableDeclarator(VariableDeclaratorId id, Expression init) {setId(id);setInit(init);}public VariableDeclarator(String variableName, Expression init) {setId(new VariableDeclaratorId(variableName));setInit(init);}public VariableDeclarator(Range range, VariableDeclaratorId id, Expression init) {super(range);setId(id);setInit(init);}@Overridepublic <R, A&qt; R accept(GenericVisitor<R, A&qt; v, A arg) {return v.visit(this, arg);}@Overridepublic <A&qt; void accept(VoidVisitor<A&qt; v, A arg) {v.visit(this, arg);}public VariableDeclaratorId getId() {return id;}public Expression getInit() {return init;}public VariableDeclarator setId(VariableDeclaratorId id) {this.id = id;setAsParentNodeOf(this.id);return this;}public VariableDeclarator setInit(Expression init) {this.init = init;setAsParentNodeOf(this.init);return this;}/*** Will create a {@link NameExpr} with the init param*/public VariableDeclarator setInit(String init) {this.init = new NameExpr(init);setAsParentNodeOf(this.init);return this;}@Overridepublic Type getType() {NodeWithElementType<?&qt; elementType = getParentNodeOfType(NodeWithElementType.class);return wrapInArrayTypes(elementType.getElementType(),elementType.getArrayBracketPairsAfterElementType(),getId().getArrayBracketPairsAfterId());}@Overridepublic VariableDeclarator setType(Type type) {Pair<Type, List<ArrayBracketPair&qt;&qt; unwrapped = ArrayType.unwrapArrayTypes(type);NodeWithElementType<?&qt; nodeWithElementType = getParentNodeOfType(NodeWithElementType.class);if (nodeWithElementType == null) {throw new IllegalStateException("Cannot set type without a parent");}nodeWithElementType.setElementType(unwrapped.a);nodeWithElementType.setArrayBracketPairsAfterElementType(null);getId().setArrayBracketPairsAfterId(unwrapped.b);return this;}
}

我们将使用Kotlin和Gradle。 我们的构建文件如下所示:

buildscript {ext.kotlin_version = '1.0.4'repositories {mavenCentral()maven {name 'JFrog OSS snapshot repo'url  'https://oss.jfrog.org/oss-snapshot-local/'}jcenter()}dependencies {classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"}
}apply plugin: 'kotlin'
apply plugin: 'application'
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'antlr'repositories {mavenLocal()mavenCentral()jcenter()
}dependencies {compile "me.tomassetti:java-symbol-solver-core:0.3.1"compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version"testCompile "junit:junit:latest.release"
}idea {module {excludeDirs += file('src/main/resources')}
}* L55 setId(id)   -&qt; com.github.javaparser.ast.body.VariableDeclarator.setId(com.github.javaparser.ast.body.VariableDeclaratorId)* L59 setId(new VariableDeclaratorId(variableName))   -&qt; com.github.javaparser.ast.body.VariableDeclarator.setId(com.github.javaparser.ast.body.VariableDeclaratorId)* L71 setId(id)   -&qt; com.github.javaparser.ast.body.VariableDeclarator.setId(com.github.javaparser.ast.body.VariableDeclaratorId)* L72 setInit(init)   -&qt; com.github.javaparser.ast.body.VariableDeclarator.setInit(com.github.javaparser.ast.expr.Expression)* L76 setId(new VariableDeclaratorId(variableName))   -&qt; com.github.javaparser.ast.body.VariableDeclarator.setId(com.github.javaparser.ast.body.VariableDeclaratorId)* L77 setInit(init)   -&qt; com.github.javaparser.ast.body.VariableDeclarator.setInit(com.github.javaparser.ast.expr.Expression)* L82 setId(id)   -&qt; com.github.javaparser.ast.body.VariableDeclarator.setId(com.github.javaparser.ast.body.VariableDeclaratorId)* L83 setInit(init)   -&qt; com.github.javaparser.ast.body.VariableDeclarator.setInit(com.github.javaparser.ast.expr.Expression)* L88 v.visit(this, arg)   -&qt; com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.body.VariableDeclarator, A)* L93 v.visit(this, arg)   -&qt; com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.body.VariableDeclarator, A)* L106 setAsParentNodeOf(this.id)   -&qt; com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)* L112 setAsParentNodeOf(this.init)   -&qt; com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)* L121 setAsParentNodeOf(this.init)   -&qt; com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)* L128 getParentNodeOfType(NodeWithElementType.class)   -&qt; com.github.javaparser.ast.Node.getParentNodeOfType(java.lang.Class<T&qt;)* L130 wrapInArrayTypes(elementType.getElementType(), elementType.getArrayBracketPairsAfterElementType(), getId().getArrayBracketPairsAfterId())   -&qt; com.github.javaparser.ast.type.ArrayType.wrapInArrayTypes(com.github.javaparser.ast.type.Type, java.util.List<com.github.javaparser.ast.ArrayBracketPair&qt;...)* L130 elementType.getElementType()   -&qt; com.github.javaparser.ast.nodeTypes.NodeWithElementType.getElementType()* L131 elementType.getArrayBracketPairsAfterElementType()   -&qt; com.github.javaparser.ast.nodeTypes.NodeWithElementType.getArrayBracketPairsAfterElementType()* L132 getId().getArrayBracketPairsAfterId()   -&qt; com.github.javaparser.ast.body.VariableDeclaratorId.getArrayBracketPairsAfterId()* L132 getId()   -&qt; com.github.javaparser.ast.body.VariableDeclarator.getId()* L137 ArrayType.unwrapArrayTypes(type)   -&qt; com.github.javaparser.ast.type.ArrayType.unwrapArrayTypes(com.github.javaparser.ast.type.Type)* L138 getParentNodeOfType(NodeWithElementType.class)   -&qt; com.github.javaparser.ast.Node.getParentNodeOfType(java.lang.Class<T&qt;)* L142 nodeWithElementType.setElementType(unwrapped.a)   -&qt; com.github.javaparser.ast.nodeTypes.NodeWithElementType.setElementType(com.github.javaparser.ast.type.Type<?&qt;)* L143 nodeWithElementType.setArrayBracketPairsAfterElementType(null)   -&qt; com.github.javaparser.ast.nodeTypes.NodeWithElementType.setArrayBracketPairsAfterElementType(java.util.List<com.github.javaparser.ast.ArrayBracketPair&qt;)* L144 getId().setArrayBracketPairsAfterId(unwrapped.b)   -&qt; com.github.javaparser.ast.body.VariableDeclaratorId.setArrayBracketPairsAfterId(java.util.List<com.github.javaparser.ast.ArrayBracketPair&qt;)* L144 getId()   -&qt; com.github.javaparser.ast.body.VariableDeclarator.getId()

建立AST非常容易,您只需调用此方法:

JavaParser.parse(file)

我还使用了几种方法来导航AST并获取特定的节点。 特别是,我将使用它仅接受方法调用。 如果您有兴趣,他们看起来像这样:

class SpecificNodeIterator<T&qt;(private val type: Class<T&qt;, private val nodeHandler: SpecificNodeIterator.NodeHandler<T&qt;) {interface NodeHandler<T&qt; {fun handle(node: T): Boolean}fun explore(node: Node) {if (type.isInstance(node)) {if (!nodeHandler.handle(type.cast(node))) {return}}for (child in node.childrenNodes) {explore(child)}}
}// this is a method extension: we had this method to the existing class "Node"
fun <T&qt; Node.descendantsOfType(type: Class<T&qt;) : List<T&qt; {val descendants = LinkedList<T&qt;()SpecificNodeIterator(type, object : SpecificNodeIterator.NodeHandler<T&qt; {override fun handle(node: T): Boolean {descendants.add(node)return true}}).explore(this)return descendants
}

什么是类型求解器? 它是知道在哪里查找类的对象。 在处理源代码时,通常会引用尚未编译的代码,但这些代码仅存在于其他源文件中。 您还可以使用JAR中包含的类或Java标准库中的类。 您只需要告诉TypeSolver在哪里寻找类,它就会弄清楚。

在我们的示例中,我们将解析JavaParser项目的源代码(如何转换成meta ?!)。 该项目的源代码位于两个不同的目录中,以获取正确的源代码和JavaCC生成的代码(您可以忽略JavaCC是什么,它与您无关)。 我们当然也使用来自Java标准库的类。 这就是我们的TypeSolver的样子:

fun typeSolver() : TypeSolver {val combinedTypeSolver = CombinedTypeSolver()combinedTypeSolver.add(JreTypeSolver())combinedTypeSolver.add(JavaParserTypeSolver(File("src/main/resources/javaparser-core")))combinedTypeSolver.add(JavaParserTypeSolver(File("src/main/resources/javaparser-generated-sources")))return combinedTypeSolver
}

这是我们调用JavaParserFacade的地方,JavaParserFacade是JavaSymbolSolver提供的类之一。 当时我们只接受一个方法调用,然后将其传递给JavaParserFacade的方法求解 。 我们得到一个MethodUsage(基本上是一个方法声明+该特定调用的参数类型的值)。 从中,我们获得MethodDeclaration,然后打印合格的签名,即类的合格名称,后跟方法的签名。 这是我们获得最终输出的方式:

var solved = 0
var unsolved = 0
var errors = 0fun processJavaFile(file: File, javaParserFacade: JavaParserFacade) {println(file)JavaParser.parse(file).descendantsOfType(MethodCallExpr::class.java).forEach {print(" * L${it.begin.line} $it ")try {val methodRef = javaParserFacade.solve(it)if (methodRef.isSolved) {solved++val methodDecl = methodRef.correspondingDeclarationprintln("  -> ${methodDecl.qualifiedSignature}")} else {unsolved++println(" ???")}} catch (e: Exception) {println(" ERR ${e.message}")errors++} catch (t: Throwable) {t.printStackTrace()}}
}

有很多事情要做,但是基本上JavaSymbolSolver会在后台完成所有繁重的工作。 一旦有了AST的节点,就可以将其扔到JavaParserFacade类上,它将为您提供可能需要的所有信息:它将找到相应的类型,字段,方法等。

问题是……我们需要更多文档和用户反馈。 我希望你们中的一些人将开始使用JavaSymbolSolver并告诉我们如何改进它。

同样,上周JavaSymbolSolver被移至JavaParser组织之下。 这意味着将来我们将与JavaParser项目更加紧密地合作。

该代码可在GitHub上找到: java-symbol-solver-examples

翻译自: https://www.javacodegeeks.com/2016/11/resolve-method-calls-java-code-using-javasymbolsolver.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/351397.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

kali2.0安装搜狗输入法

其实方法应该是是通用的 &#xff08;一开始源要配置好&#xff1a; 修改软件源APT-sources.list [python] view plaincopy vim /etc/apt/sources.list 将原来的注释掉&#xff0c;加了个阿里的#阿里云kali源deb http://mirrors.aliyun.com/kali sana main non-free contrib…

linux+vim+动不了,linux的vim按了ctrl+s之后假死的解决办法

Aqua Data Studio中文乱码使用Aqua Data Studio 查询数据时,如果表中的数据有中文时,会显示乱码,如下图: 解决方法很简单,只能更改字体即可,步骤如下: 更改字体后,显示的结果如下:C&num;调用脚本语言(三)-- IronJS 与 IronLua 简单方法性能比较1. 测试环境 1.1. 硬件环境…

aix linux操作系统,AIX--操作系统安装(AIX 6.1)

前一段时间&#xff0c;胡哥我接到老板的任务&#xff0c;要在AIX系统上安装zabbix agent呀。可是胡哥只是玩过linux对于AIX这种需要硬件支持的才能玩的高端玩意可是从来没接触过呀&#xff0c;虽说linux是类unix&#xff0c;可是与unix系统还是有区别。有啥办法了&#xff0c;…

秋季学习总结

经过这个学期的学习让我对软件工程这个专业有了新的认识&#xff0c;从c语言的学习中&#xff0c;让我慢慢懂得了如何去编写一个程序&#xff0c;但是编写一个程序也并不是那么的容易。在这个学期的学期中我总是感觉容易忘记上一节课所讲的东西&#xff0c;这个是课后自己没花时…

permgen_打破PermGen神话

permgen在我的最新文章中&#xff0c;我解释了可能导致java.lang.OutOfMemoryError&#xff1a;PermGen空间崩溃的原因 。 现在该讨论该问题的可能解决方案了。 或更确切地说&#xff0c;是关于互联网对可能解决方案的建议。 不幸的是&#xff0c;我只能说&#xff0c;当我通过…

到底是32位系统运行快还是64位系统快

首先声明一下&#xff0c;这个标题“到底是32位系统运行快还是64位系统运行快”的提法本身就是存在问题的&#xff0c;主要是由于很多网友把这个问题提炼的层次太高&#xff0c;那就是“我现在的机子是装32位系统快还是64位系统更快&#xff1f;”&#xff0c;所以就拿这个问题…

linux系统证书存储,Linux系统下如何配置Nginx的SSL安全证书

刚刚介绍了ownCloud的安装&#xff0c;有朋友问我SSL是怎么配置的&#xff0c;哎&#xff0c;为什么不去官方找&#xff0c;却来找我要呢&#xff0c;好吧&#xff0c;我知道你懒得看那些英文&#xff0c;我就介绍一下我是怎么一步步在Nginx上配置SSL的吧。首先你要确保你安装了…

命令界面:使用Java中的动态API处理Redis

Redis是一个数据存储&#xff0c;支持190多个已记录命令和450多个命令排列。 社区积极支持Redis开发&#xff1b; 每个主要的Redis版本都附带新命令。 今年&#xff0c;Redis向第三方供应商开放&#xff0c;以开发可扩展Redis功能的模块。 对于客户端开发人员和Redis用户而言&a…

Python数据库连接池DBUtils

DBUtils是Python的一个用于实现数据库连接池的模块 此连接池有两种连接模式&#xff1a; DBUtils提供两种外部接口&#xff1a; PersistentDB &#xff1a;提供线程专用的数据库连接&#xff0c;并自动管理连接。 PooledDB &#xff1a;提供线程间可共享的数据库连接&…

够用的 Python 写日志的知识——标准日志模块logging简介

前一段工作的时候用到了python写后台系统&#xff0c;需要把一些系统的行为记录下来。本着不要去重复发明轮子的精神&#xff0c;就去搜索了一下python的系统库本身是否有写日志的模块。果然有。python语言作为一门接口简单&#xff0c;标准库强大的语言&#xff0c;果然没有令…

vivox7刷linux系统,Vivo 找来宋仲基帮你送 X7

虽说有极致的 Xplay5 用来打品牌&#xff0c;但真正跑起量来&#xff0c;Vivo 实际上靠得还是以明星代言、外型、自拍等特性为卖点的中端产品线。这不&#xff0c;他们刚刚又在北京发布了全新的 X7 系列&#xff0c;这次找来了大势韩星宋仲基&#xff0c;美其名曰「有了你就有了…

Gradle配置

配置远程仓库 在gradle目录下的init.d目录中创建名为init.gradle文件&#xff0c;内容如下&#xff1a; allprojects{repositories {def REPOSITORY_URL http://localhost:8081/nexus/content/groups/public/all { ArtifactRepository repo ->if(repo instanceof MavenArti…

UML类图实例

首先是复习一下UML中九种图的理解&#xff1a;http://xhf123456789plain.blog.163.com/blog/static/172880482201192222144421/ 画用例图&#xff1a;http://xhf123456789plain.blog.163.com/blog/static/172880482201192221826110/ 下面是类图的实例&#xff08;好像大话设计中…

836c语言程序设计,2017年辽宁师范大学计算机应用研究所836C语言程序设计考研强化模拟题...

一、选择题1&#xff0e; 以下叙述中正确的是( )。A. 在scanf 函数的格式串中&#xff0c;必须有与输入项一一对应的格式转换说明符B. 只能在printf 函数中指定输入数据的宽度&#xff0c;而不能在scanf 函数中指定输入数据占的宽度C.scanf 函数中的字符串是提示程序员的&#…

days to_days_Java2Days 2012:Java EE

days to_daysJava2Days会议是东欧的主要活动&#xff0c;目的是介绍Java开发的最新趋势。 今年&#xff0c;该活动于10月25日至26日在保加利亚的索非亚举行。 我在那里&#xff0c;并有机会与一些来自SAP的同事一起品尝了一些最新的Java&#xff0c;云和移动内容&#xff0c;这…

c语言静态成员变量重名会怎么样,C++中静态成员函数与静态成员变量(static )...

C中静态成员函数与静态成员变量(static )这篇介绍了静态成员函数与静态成员变量&#xff0c;是我的读书笔记&#xff0c;我希望它够简短但又比较全面&#xff0c;起到复习的作用。如果有一些C知识记不清楚了&#xff0c;它可以帮你很快回忆起来。复习C语言的static关键字(1)加在…

JVM简单学习

jvm与字节码 jvm只需关注字节码文件 jvm由哪些部分构成 1.类加载子系统&#xff0c;将磁盘中的字节码文件加载到方法区的内存空间中 类加载器分两种&#xff1a;引导类加载器是jvm底层中用C和C语言写的 各个默认的类加载器的不同区别在于 各自默认负责要加载的类的目录不一…

谈一谈自己对依赖、关联、聚合和组合之间区别的理解

在学习面向对象设计对象关系时&#xff0c;依赖、关联、聚合和组合这四种关系之间区别比较容易混淆。特别是后三种&#xff0c;仅仅是在语义上有所区别&#xff0c;所谓语义就是指上下文环境、特定情景等。他们在编程语言中的体现却是基本相同的&#xff0c;但是基本相同并不等…

Java Bullshifier –生成大量随机代码库

生成大量随机Java应用程序的命令行工具 您一直在等待的命令行工具。 或不。 毕竟&#xff0c;这是很深奥的。 无论哪种方式&#xff0c;它对某些人都非常有用&#xff0c;而对其他人来说却是一个有趣的实用程序。 Bullshifier是由David Levanon和Hodaya Gamliel开发的内部Over…

二级c语言光盘,二级c语言(光盘).doc

1程序设计题&#xff1a; 请编写一个函数 unsigned fun (unsigned w ) w是一个大于10的无符号整数。例如&#xff1a;W值为5923&#xff0c;则函数返回923&#xff1b;W值为923&#xff0c;则函数返回23。if ( w >10000 ) w % 10000 ; 程序修改题: m i; 和 if( a[k]>a[m]…