您的位置:首页 > 编程语言 > Java开发

找到java代码中没有被使用的公用方法

2008-07-27 14:10 573 查看
最近,我打算对我们项目的代码进行清理,准备把一些没有被使用到的公用方法清理掉,但是我在网络找了一遍,像PMD,Findbugs等静态工具,都只能找到没有被使用的私有方法。



无奈之下,只能直接写代码来实现这个功能,具体代码如下:



package com;

import java.io.File;
import java.io.FileReader;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;

public class FindUnUsedCode {
public static final int TYPE_METHOD = 0; //方法
public static final int TYPE_ATTRIBUTE = 1; //属性

/**
* 类对象
*/
class ClassObject{
public List<String> methods = new ArrayList<String>(); //公用方法集合
public String className; //类名
public List<String> attributes = new ArrayList<String>(); //属性名
}

/**
* 熟悉对象
*/
class MethodObject{
public String methodName; //方法名
}

class UnUsedCode{
public String className; //类名
public String codeName; //方法名或者属性名
public int type; //0:方法名,1:属性名
public String descript; //描述
}

//类集合
private List<ClassObject> classList = new ArrayList<ClassObject>();

//java定义的数据类型
private String[] dataTypes = {"void", "int", "boolean", "long", "char", "float", "double"};

//java定义的访问权限
private String[] callAuths = {"public", "friendly", "protected", "private"};

//java的关键字
private String[] keyWords = {"public", "friendly", "protected", "private", "void", "int", "boolean", "long", "char", "float", "double"
, "{", "}"};

/**
* 检查一个文件名是否java文件
* @param fileName
* @return
*/
private boolean checkIsJava(String fileName)
{
boolean result = false;

if (fileName.lastIndexOf(".java") != -1)
{
result = true;
}

return result;
}

/**
* 分析java文件,返回类对象
* @param fullName
* @return
*/
public ClassObject analyseJavaFile(String path, String fileName) throws Exception
{
//全路径
String fullName = path + "/" + fileName;

//文件对象
File file = new File(fullName);

//创建对象
ClassObject classObject = new ClassObject();

//设置类名
classObject.className = fileName.substring(0, fileName.length()-5);

//得到文件读对象
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");

//读取一行数据
String line = "";

do
{
line = randomAccessFile.readLine();

if (line == null)
{
break;
}
else
{
//去掉前后空格
line = line.trim();
}

//System.out.println("line:" + line);

if (line.indexOf(" class ") != -1)
{
//为类定义行,则不处理该行
continue;
}

//判断是否公用对象
if (line.startsWith("public"))
{
//把数据拆分出来
String[] strs = line.split(" ");

//顺序获取数据,从第三个开始读,因为第一个为public,第二个为数据类型,第三个才可能是名字
for (int i = 2; i < strs.length; i++)
{
//判断是否java的关键字
if (isKeyWords(strs[i]))
{
continue;
}

//判断是否以小写字符开始
if (isStartWithLower(strs[i]))
{
//找到是否包含有括号
int loc = strs[i].indexOf("(");

if (loc == -1)
{//不包含扩展
if (strs[i].indexOf(";") == -1)
{//不包含分号
if ((strs.length > (i+1)) && (strs[i+1].indexOf("(") == -1))
{
//下一个数据也不包含括号,那么则是属性
classObject.attributes.add(strs[i]);

break;
}
else
{
//下个数据包含括号,则是方法
classObject.methods.add(strs[i]);

//System.out.println("22222222222222222:" + line);

break;
}
}
else
{
//没有括号,而且已经分号结束了,那么则是属性名
classObject.attributes.add(strs[i].substring(0, strs[i].length() - 1 ));

break;
}
}
else
{
//包含了括号,则是方法
classObject.methods.add(strs[i].substring(0, loc));

//System.out.println("1111111111111111:" + line);

break;
}
}
}
}
}while (line != null);

return classObject;
}

/**
* 判断字符串是否以小写字符开始
* @param str
* @return
*/
public boolean isStartWithLower(String str)
{
return str.startsWith(str.toLowerCase().substring(0, 1));
}

/**
* 判断是否java的关键字
* @param str
* @return
*/
public boolean isKeyWords(String str)
{
return isInculeList(str, keyWords);
}

/**
* 判断是否java的数据类型
* @param str
* @return
*/
public boolean isDataType(String str)
{
return isInculeList(str, dataTypes);
}

/**
* 判断是否java的访问权限类型
* @param str
* @return
*/
public boolean isCallAuth(String str)
{
return isInculeList(str, callAuths);
}

/**
* 判断一个字符串是否在一个数据列表中
* @param str
* @param lists
* @return
*/
public boolean isInculeList(String str, String[] lists)
{
boolean result = false;

//获取java的所有类型
for (int i = 0; i < lists.length; i++)
{
if (lists[i].equals(str))
{
//包含在列表中
result = true;

break;
}
}

return result;
}

/**
* 去类集合
* @param path
* @return
*/
public List<ClassObject> getClassList(String path) throws Exception
{
File file = new File(path);

String[] list = file.list();

//文件名
String fileName = "";

//类对象
ClassObject classObject;

//循环获取数据
for (int i = 0; i < list.length; i++)
{
//得到文件的全路径
fileName = path + "/" + list[i];

//得到文件对象
file = new File(fileName);

//判断是否java文件
if (checkIsJava(list[i]))
{
//得到java数据
classObject = analyseJavaFile(path, list[i]);

if (classObject != null)
{
//增加一个数据
this.classList.add(classObject);
}
}
else if (file.isDirectory())
{//是一个目录
//递归执行
getClassList(fileName);
}
}

return this.classList;
}

/**
* 文件中是否包含某个字符串
* @param fullPath
* @param str
* @return
* @throws Exception
*/
public boolean isIncludeStr(String fullPath, String str) throws Exception
{
List<String> list = new ArrayList<String>();
list.add(str);

return isIncludeStrs(fullPath, list);
}

/**
* 文件中是否包含了知道的字符串
* @param fullPath
* @param strs
* @return
*/
public boolean isIncludeStrs(String fullPath, List<String> strs) throws Exception
{
boolean result = false;

List<String> tempStrs = strs;

//得到文件读对象
RandomAccessFile randomAccessFile = new RandomAccessFile(fullPath, "r");

//读取一行数据
String line = "";

do
{
//读一行
line = randomAccessFile.readLine();

if (line == null)
{
break;
}
else
{
//去掉前后空格
line = line.trim();
}

if ((tempStrs != null) && (!tempStrs.isEmpty()))
{
for (int i = 0; i < tempStrs.size(); i++)
{
//包含改字符串
if (line.indexOf(tempStrs.get(i)) != -1)
{
//去掉该数据
tempStrs.remove(i);
}
}
}
else
{
//已经为空,则表示已经完全匹配了所以字符串,跳出
break;
}
}while (line != null);

if ((tempStrs == null) || (tempStrs.isEmpty()))
{
//完全比配
result = true;
}

return result;
}

/**
* 检查代码是否被使用,0:被使用了,1:没有被使用,2:无法确定
* @param path
* @param className
* @param codeName
* @return
*/
public int checkUsed(String path, String className, String codeName) throws Exception
{
//没有被使用
int result = 1;

File file = new File(path);

//得到列表
String[] list = file.list();

//全路径
String fullPath = "";

List<String> checkList = new ArrayList<String>();
checkList.add(className);
checkList.add(codeName);

if ((list != null) && (list.length > 0))
{
//循环获取数据
for (int i = 0; i < list.length; i++)
{
//如果为同一个类,则不检查
if (list[i].equals(className + ".java"))
{
continue;
}

//得到文件的全路径
fullPath = path + "/" + list[i];

file = new File(fullPath);

//判断是文件还是目录
if (file.isFile())
{
if (isIncludeStrs(fullPath, checkList))
{
//既包含了类名,又包含方法名,则表示该方法,铁定被使用了
return 0;
}
else if (isIncludeStr(fullPath, codeName))
{
//调用了方法,且没有找到类,则无法确定
result = 2;

//继续判断下一个
continue;
}
}
else if (file.isDirectory())
{//是一个目录
//递归执行
checkUsed(fullPath, className, codeName);
}
}
}

return result;
}

/**
* 获取没有被使用的代码
* @param path
* @param className
* @param codeNames
* @param type
* @return
* @throws Exception
*/
public List<UnUsedCode> getUnUsedCode(String path, String className, List<String> codeNames, int type) throws Exception
{
List<UnUsedCode> result = new ArrayList<UnUsedCode>();
UnUsedCode unUsedCode;

if ((codeNames != null) && (!codeNames.isEmpty()))
{
//循环获取属性
for (int j = 0; j < codeNames.size(); j++)
{
String codeName = codeNames.get(j);

//判断是否被使用
int usedType = checkUsed(path, className, codeName);

//没有被使用
if (usedType != 0)
{
//创建对象
unUsedCode = new UnUsedCode();

unUsedCode.className = className; //类名
unUsedCode.codeName = codeName; //属性名
unUsedCode.type = type; //类型为属性

if (usedType == 1)
{
unUsedCode.descript = "没有被使用";
}
else if (usedType == 2)
{
unUsedCode.descript = "无法确定";
}

//增加一条数据
result.add(unUsedCode);
}
}
}

return result;
}

/**
* 得到未使用的代码
* @param path
* @return
*/
public List<UnUsedCode> getUnUsedCode(String path) throws Exception
{
//结果
List<UnUsedCode> result = new ArrayList<UnUsedCode>();

//得到类对象
List<ClassObject> classList = getClassList(path);

ClassObject classObject;

List<UnUsedCode> unUsedAttrList;

List<UnUsedCode> unUsedMethodList;

//数据不为空
if ((classList != null) && (!classList.isEmpty()))
{
//循环获取数据
for (int i = 0; i < classList.size(); i++)
{
//获取一个数据
classObject = classList.get(i);

//得到一个类中没有使用的属性列表
unUsedAttrList = getUnUsedCode(path, classObject.className, classObject.attributes, TYPE_ATTRIBUTE);

if ((unUsedAttrList != null) && (!unUsedAttrList.isEmpty()))
{
//增加数据
result.addAll(unUsedAttrList);
}

//得到一个类中没有使用的属性列表
unUsedMethodList = getUnUsedCode(path, classObject.className, classObject.methods, TYPE_METHOD);

if ((unUsedMethodList != null) && (!unUsedMethodList.isEmpty()))
{
//增加数据
result.addAll(unUsedMethodList);
}
}
}

return result;
}

public static void main(String[] args)
{
FindUnUsedCode findUnUsedCode = new FindUnUsedCode();

try
{
List<UnUsedCode> list = findUnUsedCode.getUnUsedCode("C:/com");

if ((list != null) && (!list.isEmpty()))
{
for (int i = 0; i < list.size(); i++)
{
UnUsedCode unUsedCode = list.get(i);

System.out.println(unUsedCode.className + "." + unUsedCode.codeName
+ " " + (unUsedCode.type==TYPE_METHOD?"方法":"属性") + " " + unUsedCode.descript);
}

}
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐