通过使用BCEL解析Java字节码来确定LCOM4(方法中缺乏内聚性)
我已经构建了一个程序,它接收一个提供的“.class”文件并使用BCEL解析它,但是当涉及到使用结果对象来确定LCOM4值时,我有点不知所措。我浏览了整个网络,试图找到一个关于它的合适的教程,但到目前为止我还没有找到(我也阅读了关于BCEL的整个javadoc)。所以我想在这个问题上得到一些帮助,比如在一些详细的教程或代码片段中,可以帮助我理解如何做到这一点 好的,让我们定义一个类来表示一组字段和方法:通过使用BCEL解析Java字节码来确定LCOM4(方法中缺乏内聚性),java,bytecode,bcel,lcom,Java,Bytecode,Bcel,Lcom,我已经构建了一个程序,它接收一个提供的“.class”文件并使用BCEL解析它,但是当涉及到使用结果对象来确定LCOM4值时,我有点不知所措。我浏览了整个网络,试图找到一个关于它的合适的教程,但到目前为止我还没有找到(我也阅读了关于BCEL的整个javadoc)。所以我想在这个问题上得到一些帮助,比如在一些详细的教程或代码片段中,可以帮助我理解如何做到这一点 好的,让我们定义一个类来表示一组字段和方法: public class Group { private final Set<
public class Group {
private final Set<String> fields = new HashSet<>();
private final Set<String> methods = new HashSet<>();
public Group addFields(String...fields) {
for (String field: fields) {
this.fields.add(field);
}
return this;
}
public Group addMethods(String... methods) {
for (String method: methods) {
this.methods.add(method);
}
return this;
}
public int fields() {
return fields.size();
}
public int methods() {
return methods.size();
}
public boolean intersects(Group other) {
for (String field: other.fields) {
if (fields.contains(field)) {
return true;
}
}
for (String method: other.methods) {
if (methods.contains(method)) {
return true;
}
}
return false;
}
public void merge(Group other) {
fields.addAll(other.fields);
methods.addAll(other.methods);
}
@Override
public String toString() {
return "Group{" + "fields=" + fields + ", methods=" + methods + '}';
}
}
公共类组{
私有最终集字段=新HashSet();
私有最终集方法=新HashSet();
公共组添加字段(字符串…字段){
用于(字符串字段:字段){
this.fields.add(字段);
}
归还这个;
}
公共组addMethods(字符串…方法){
for(字符串方法:方法){
此.methods.add(方法);
}
归还这个;
}
公共整型字段(){
返回字段。size();
}
公共int方法(){
返回方法。size();
}
公共布尔相交(组其他){
for(字符串字段:其他.fields){
if(fields.contains(field)){
返回true;
}
}
for(字符串方法:其他.methods){
if(methods.contains(method)){
返回true;
}
}
返回false;
}
公共无效合并(组其他){
fields.addAll(其他.fields);
方法:addAll(其他方法);
}
@凌驾
公共字符串toString(){
返回“组{“+”字段=“+fields+”,方法=“+methods+'}”;
}
}
我们首先用类中定义的每个字段的组填充组列表,然后,对于每个方法,我们用代码中引用的字段和方法构建一个组,然后通过合并和删除与方法组相交的每个组来减少组列表
下面是加载类的组的java代码。LCOM4是组。大小()
私有列表加载组(文件)引发IOException{
try(InputStream in=新文件InputStream(文件)){
ClassParser=newClassParser(在,file.getName()中);
JavaClass clazz=parser.parse();
字符串className=clazz.getClassName();
ConstantPoolGen cp=新的ConstantPoolGen(clazz.getConstantPool());
列表组=新的ArrayList();
for(字段:clazz.getFields()){
groups.add(newgroup().addFields(field.getName());
}
for(方法:clazz.getMethods()){
groupgroup=newgroup().addMethods(method.getName());
Code=method.getCode();
指令列表instrs=新的指令列表(code.getCode());
用于(指示手柄ih:仪表){
指令指令instr=ih.getInstruction();
if(仪表实例现场指令){
现场指令fld=(现场指令)仪表;
if(fld.getClassName(cp).equals(className)){
group.addFields(fld.getFieldName(cp));
}
}else if(InvokeInstruction的指令实例){
调用指令inv=(调用指令)指令;
if(inv.getClassName(cp).equals(className)){
group.addMethods(inv.getMethodName(cp));
}
}
}
if(group.fields()>0 | | group.methods()>1){
int i=groups.size();
而(i>0){
--一,;
g组=组。获取(i);
如果(g.相交(组)){
合并组(g);
删除(i);
}
}
组。添加(组);
}
}
返回组;
}
}
好的,让我们定义一个类来表示一组字段和方法:
public class Group {
private final Set<String> fields = new HashSet<>();
private final Set<String> methods = new HashSet<>();
public Group addFields(String...fields) {
for (String field: fields) {
this.fields.add(field);
}
return this;
}
public Group addMethods(String... methods) {
for (String method: methods) {
this.methods.add(method);
}
return this;
}
public int fields() {
return fields.size();
}
public int methods() {
return methods.size();
}
public boolean intersects(Group other) {
for (String field: other.fields) {
if (fields.contains(field)) {
return true;
}
}
for (String method: other.methods) {
if (methods.contains(method)) {
return true;
}
}
return false;
}
public void merge(Group other) {
fields.addAll(other.fields);
methods.addAll(other.methods);
}
@Override
public String toString() {
return "Group{" + "fields=" + fields + ", methods=" + methods + '}';
}
}
公共类组{
私有最终集字段=新HashSet();
私有最终集方法=新HashSet();
公共组添加字段(字符串…字段){
用于(字符串字段:字段){
this.fields.add(字段);
}
归还这个;
}
公共组addMethods(字符串…方法){
for(字符串方法:方法){
此.methods.add(方法);
}
归还这个;
}
公共整型字段(){
返回字段。size();
}
公共int方法(){
返回方法。size();
}
公共布尔相交(组其他){
for(字符串字段:其他.fields){
if(fields.contains(field)){
返回true;
}
}
for(字符串方法:其他.methods){
if(methods.contains(method)){
返回true;
}
}
返回false;
}
公共无效合并(组其他){
fields.addAll(其他.fields);
方法:addAll(其他方法);
}
@凌驾
公共字符串toString(){
返回“组{“+”字段=“+fields+”,方法=“+methods+'}”;
}
}
我们首先用类中定义的每个字段的组填充组列表,然后,对于每个方法,我们用代码中引用的字段和方法构建一个组,然后通过合并和删除与方法组相交的每个组来减少组列表
下面是加载类的组的java代码。LCOM4是组。大小()
私有列表加载组(文件)引发IOException{
try(InputStream in=新文件InputStream(文件)){
ClassParser=newClassParser(在,file.getName()中);
JavaClass clazz