看开源项目源代码或者看项目源码的时候,常常觉得代码看起来比较啰嗦,总觉得有些的应该可以简化的。
比如:
1 过多的getter、setter 这些显然是没技术含量的,但是它夹杂在类的其他代码中,影响了阅读。我的做法是把去掉其getter、setter,然后它直接改为public 变量。——虽然这有违java封装原则,但是我想这却是有利于代码阅读的。。
2 过多的注释,一些开源项目往往就是大版大版的注释,注释多是好是坏姑且不论,但是有时候我们只是想看源码,不想看注释,这个时候它就非常讨嫌了!
3 过多的try catch 等异常扑捉。 这显然也是影响阅读的,试想,如果关键代码就那么一行一个方法20个字符之内,外面却包了3、4个try catch,多烦人啊,最后还有finally。。。 当然,如果想详细了解源码,彻底弄明白其功能,仔细阅读try catch是有必要的,但有时候,我们只想快速的、大致的阅读一下源码,这个时候也有必要简化一下那个类了。
4 日志,一般来说,日志只是处理调试信息、警告信息、异常信息等用的, 去掉它并不影响功能
5 注解 有些annotation并不是必须的,去掉完全不影响阅读,比如:@Override、@SuppressWarnings..等
众所周知,看源码并不是一件简单的事,因为,我们常常没有那个对应的UML图,功能说明啊等。(不知道为什么都这样。。。)
要是能简化代码,那么再来阅读就会轻松多了!本想这么个简单的功能,别人应该已经做出来了的。可是,我网上搜索却总也找不到。——难道大家都没有这方面的考虑吗??
困扰了我很久,今天有点时间,想起这事,于是自己写了一个简单实现:
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Stack; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.luobk.po.VarObject; /** * 代码阅读优化器 CodeSimplifier或者也可以称为 CodePurifier吧 * goSimplifyProject 只针对 目录 * 若是 想直接的simplify一个java文件,则用simplifyFile即可 * */ public class CodeSimplifier { // public static String SOURCE_DIR = "D:\\WS\ABC\\src"; public static String SOURCE_DIR = "D:\\WS\\CodeSimplifier\\src"; public static String DEST_DIR = "D:\\WS\\CodeSimplifier\\src3"; public static String SOURCE_FOLDER = "src"; public static String LOGGER_NAME = "log"; public static boolean USE_SOURCE_FOLDER = false; /** * * @param args * @throws IOException */ public static void main(String[] args) throws IOException { // TODO Auto-generated method stub goSimplifyProject(SOURCE_DIR,DEST_DIR); // simplifyFile(new File(SOURCE_DIR), DEST_DIR); // System.out.println("sfasf".matches("[.]+")); // System.out.println("asf " + // "a\" f艾丝凡 f\nasf\nnnbbsa;\"aa".matches("a\"(.|\\s)*;\"aa")); // System.out.println("\n".matches("(\\s+)")); // System.out.println("sfasf".matches(".*asf")); // .+ 。* 是可以自动伸缩的 , 默认的 。。。 非贪婪模式?? // String ss = "System.out. println(\"sfas r asfa fas \");\n" + // "System.out. println(\"sfas + \n asfa fas \");"; // System.out.println("ss . replaceAll : "+ss. // replaceAll("\\s+System\\s*\\.\\s*out\\s*\\.\\s*print(ln)?\\s*\\(\\s*\"(.|\\s)*\"\\s*\\)\\s*;","")); // StringBuffer sb = new StringBuffer("abcdef\nxyz\n>"); // sb.deleteCharAt(sb.length()-1); // System.out.println("matches++ = "+"sfaaf".matches(".{6}"));// + 后面的 {n} 失效 // System.out.println("matches++ = "+"fasf \n}".matches(".+")); // 匹配任何字符包括' ',但是不包括 \n等 // System.out.println("sfaf>s]f[s.".replaceAll("]","A"));// 到底要不要转义 [] 啊!! // sb.reverse 有用的方法!是String 没有提供的! // String filePath = "D:\\iEMPWorkspaces\\CodePurifier\\src\\po\\"; // String projectPath = "D:\\iEMPWorkspaces\\CodePurifier\\src2\\Bootstrap.java"; // String destDir = "D:\\iEMPWorkspaces\\CodePurifier\\src3\\"; // System.out.println("ddasfasf aa\n = asf qwf".replaceAll("\\s{2}", "X")); // System.out.println("ddasfasf aa\n = 2asf qwf".replaceAll("\\s[2]", "X")); // System.out.println(capitalize("asfaf")); // File f = new File("D:\\iEMPWorkspaces\\CodePurifier\\src2\\sdaf.java"); // f.mkdir(); // FileOutputStream fos = new FileOutputStream(f); // BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos)); // bw.write(destDir);// if we don't write sth , the file will never be created,just in mem. // bw.close(); // System.out.println("f.length()=="+f.length()+" f.exists();===+"+f.exists()); // System.out.println(" is DIR == "+ f.getCanonicalPath()+"\\"+f.getName()); } public static void goSimplifyProject(String projectPath,String destprojectPath) throws IOException { File destProjectDir = new File(destprojectPath); if(!destProjectDir.exists())destProjectDir.mkdir(); if(!projectPath.endsWith("\\")) projectPath = projectPath + "\\"; if(!destprojectPath.endsWith("\\")) destprojectPath = destprojectPath + "\\"; File sourceDir = null; if(USE_SOURCE_FOLDER)sourceDir = new File(projectPath+SOURCE_FOLDER+"\\"); else sourceDir = new File(projectPath); simplifyProject(sourceDir,destprojectPath,true); } public static void simplifyProject(File fileOrDir,String destDir,boolean isRoot) throws IOException { if(fileOrDir.isDirectory()) { /** 此种过滤行不通! FilenameFilter filter = new FilenameFilter() { private String type = ".java"; @Override public boolean accept(File dir, String name) { //return true; return name.endsWith(type); } };*/ File[] files = fileOrDir.listFiles(); for (int i = 0; i < files.length; i++) { File file = files[i]; if(isRoot) { if(USE_SOURCE_FOLDER)destDir = destDir+SOURCE_FOLDER+"\\"; File destRootDir = new File(destDir); if(!destRootDir.exists())destRootDir.mkdir(); simplifyProject(file,destDir,false); }else { // Build the new directory,othewise we'll got: //"java.io.FileNotFoundException: D:\iEMPWorkspaces\CodePurifier\src2\po\Sdfa.java (系统找不到指定的路径。)" //System.out.println("lastDir=="+lastDir); String lastDir = fileOrDir.getName(); File directory = new File(destDir+lastDir); if(!directory.exists())directory.mkdir(); simplifyProject(file,destDir+lastDir+"\\",false); } } }else if(fileOrDir.isFile()){ if(fileOrDir.getName().endsWith(".java"))simplifyFile(fileOrDir,destDir); } } /** * * FOR JAVA FILE ONLY CURRENTLY * * REMOVE THE COMMENTS AND THE GETTER/SETTER, AND CHANGE THE MODIFIRE OF RALATED ONE TO 'PUBLIC' * * ASSUME THAT THE GETTER/SETTER USES PARAMETER AS THE SAME NAME OF THE VARAIBLE * * THATS ALL * * @param file * @throws IOException */ @SuppressWarnings({ "unchecked", "rawtypes" }) public static void simplifyFile(File file,String destDir) throws IOException { FileInputStream fis = new FileInputStream(file); System.out.println(file.getAbsolutePath()); String outputFile = destDir+file.getName(); //System.out.println("output FIle Path"+outputFile); FileOutputStream fos = new FileOutputStream(new File(outputFile));// assume the outputFile is not the input one BufferedReader br = new BufferedReader(new InputStreamReader(fis)); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos)); boolean isComments = false; boolean isEmptyRow = false; String line = ""; String oline = ""; List privateVars = new ArrayList(); StringBuffer sb = new StringBuffer(); while((line=br.readLine())!=null) { oline = line; line = line.trim().replaceAll("\\s+", " "); // white line if("".equals(line)) { continue; } // 去掉注释 //if(isComments&&!(line.endsWith("*/"))&&!line.endsWith("*/ "))continue; //TODO 暂不考虑 行中/*前面还有代码的情况 // 眼考虑 /* */在同一行的情况,—— 如果*/后面还有内容,则不管了 ! if(line.startsWith("/*")&&(line.endsWith("*/")||line.endsWith("*/ "))) { continue; } if(line.startsWith("/*")) { isComments = true; continue; } if(isComments&&!line.endsWith("*/")&&!line.endsWith("*/ ")) {//line.startsWith("*")&& //ifComments = true; continue; } //TODO 暂不考虑 行中*/后面还有代码的情况 if(line.endsWith("*/")||line.endsWith("*/ ")) { //System.out.println("line : "+line); isComments = false; continue; } if(line.startsWith("//")) { continue; } String[] strs = line.replace(';', ' ').trim().split(" "); if(line.startsWith("private ") &&strs.length==3 && line.endsWith(";")) { //line = line.replaceFirst("private", "public"); //oline = oline.replaceFirst("private", "public"); VarObject vo = new VarObject(); vo.setVar(strs[2]); vo.setType(strs[1]); privateVars.add(vo); } String regex = "\\s*[\\}\\)\\]>]\\s*"; if(oline.matches(regex)) { if(isEmptyRow) { sb.deleteCharAt(sb.length()-1); sb.append(line+"\n"); } else sb.append(oline+"\n"); isEmptyRow = true; }else { isEmptyRow = false; sb.append(oline+"\n"); } } br.close(); String ret = sb.toString(); System.out.println("Before:\n" + ret); //ret = ret.replaceAll("\\) ",")").replaceAll("\\s?\\(\\s+\\)\\s?", "()");//.replaceAll("\n", ""); ret = filterGetterSetters(ret, privateVars); ret = filterLogs(ret); ret = filterAnnotations(ret); ret = filterTryCatchs(ret); bw.write(ret); bw.close(); System.out.println("After:\n" + ret); } // 无止境的 CLRF 空字符。。。 \\s* 繁琐。。。 private static String filterAnnotations(String str) { String regex = "((@\\s*Override)|(@\\s*SuppressWarnings\\s*\\(.*\\)))\\s*"; str = str.replaceAll(regex, ""); return str; } private static String filterGetterSetters(String str,List privateVars) { for (Iterator iterator = privateVars.iterator(); iterator.hasNext();) { VarObject vo = (VarObject) iterator.next(); String getterRegEx = "\\s+public\\s+"+vo.getType()+"\\s+get"+capitalize(vo.getVar())+"\\s*\\(\\s*\\)\\s*\\{\\s*return\\s+"+vo.getVar()+"\\s*;\\s*\\}"; String setterRegEx = "\\s+public\\s+void\\s+set"+capitalize(vo.getVar())+"\\(\\s*" +vo.getType()+"\\s+\\w+\\s*\\)\\s*\\{\\s*(this\\.)?"+vo.getVar()+"\\s*=\\s*\\w+;\\s*\\}"; Matcher mgetter = Pattern.compile(setterRegEx).matcher(str); Matcher msetter = Pattern.compile(getterRegEx).matcher(str); if(mgetter.find() && msetter.find()){ str = mgetter.replaceAll(""); str = msetter.replaceAll(""); str = str.replaceFirst("private\\s+"+vo.getType()+"\\s+"+vo.getVar(), "public "+vo.getType()+" "+vo.getVar()); //oline = oline.replaceFirst("private", "public"); } } return str; } // TODO 要考虑 log 里面内容换行的情况 。 // TODO 要考虑 System.out.println 里面内容换行的情况 ,但是 如果 是 System.\n out\n .println的情况就不管了,实在太繁琐。。。。。 private static String filterLogs(String str) { String regexLog = "\\s+((private)|(public))\\s+.+log\\s+=\\s+Logger\\.getLogger.+;"; String regex = LOGGER_NAME+"\\s*\\.\\s*((debug)|(warn)|(error)|(fatal)|(finest)|(finer)|(fine)|(warning)|(severe))\\s*\\(\\s*\".*\"\\s*\\)\\s*;\\s*"; //String regex = "log\\s*\\.\\s*[(fine)|(severe)]"; //String regex4Javalog = "^log\\s*\\.\\s*[(finest)(finer)(fine)(warning)(severe)]\\s*\\(\\s*\".*\"\\s*\\)\\s*;"; str = str.replaceAll(regexLog, "").replaceAll(regex, ""); //if(Pattern.compile(regex).matcher(str).find()) { //} // TODO (.|\\s)*此处引起异常 //str = str.replaceAll("\\s+System\\s*\\.\\s*out\\s*\\.\\s*print(ln)?\\s*\\(\\s*\"(.|\\s)*\"\\s*\\)\\s*;", ""); return str; } // 太复杂, 而且可能影响原功能,所以,只做简单处理。。 这显然是会影响原有功能的!! private static String filterTryCatchs(String str) { // TODO String regexTry = "";//"try\\s*\\{\\s*";// 暂不处理 String regexCatch = "\\}\\s*catch\\s*\\(\\s*\\w+\\s+\\w+\\s*\\)\\s*\\{\\s*.+\\s*"; String regexFinally = "";//"\\s*\\}\\s*finally\\s*\\{\\s*.+\\s*\\}";// 暂不处理 //str = str.replaceAll(regexTry, "").replaceAll(regexCatch, "").replaceAll(regexFinally, ""); // if(Pattern.compile(regexCatch).matcher(str).find()) { str = str.replaceAll(regexCatch, " }catch(Exception e){e.printStackTrace();"); } return str; } // 将 }\n } \n ) \n) ... 的情况合并成 } } ) )... private static String foldEmptyRow(String str) { // TODO return str; } public static String capitalize(String str) { if(str==null)return ""; if(str.length()==1)return str.toUpperCase(); Character firstLetter = str.charAt(0); return Character.toUpperCase(firstLetter)+str.substring(1); } @SuppressWarnings("unchecked") public static boolean checkParetheis(String str) { Matcher matcher = Pattern.compile("[\\(\\{\\[<\\)\\}\\]>\"\']").matcher(str); Pattern p = Pattern.compile("[\\)\\}\\]>\"\']"); Stack stack = new Stack<>(); while(matcher.find()) { String c = matcher.group(); if(p.matcher(c).matches()) { if(stack.size()>0){ char top = ((String) stack.peek()).charAt(0); if(c.charAt(0)==converseChar(top)) { stack.pop(); }else { stack.push(c); } }else { stack.push(c); } }else { stack.push(c); } } System.out.println("stack remains :" +stack.toString()); if(stack.size()>0)return false; return true; } @SuppressWarnings("unchecked") public static boolean checkParetheis(File f) { if(f.exists()) { FileInputStream fis = null; try { fis = new FileInputStream(f); char c = 'a'; int ifEnd = 0; Stack stack = new Stack<>(); while((ifEnd=fis.read())!=-1) {// -1 是可以转换为char的,但是 转换之后 c 已经不再是 -1 !!! c = (char)ifEnd; System.out.print(c); if(c=='('||c=='{'||c=='<'||c=='[')stack.push(c); else if(c==')'||c=='}'||c=='>'||c==']') { char top = (char) stack.peek(); if(c==converseChar(top)) { stack.pop(); }else { stack.push(c); } }else if(c=='"'||c=='\'') { if(stack.size()>0){ char top = (char) stack.peek(); if(c==converseChar(top)) { stack.pop(); }else { stack.push(c); } }else { stack.push(c); } } } System.out.println("ifEnd :"+ifEnd+" c :"+ (char)(-1)); if(stack.size()==0)return true; System.out.println("stack remains :" +stack.toString()); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); }catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { try { fis.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } return false; } public static char converseChar(char c) { if(c=='(')return ')'; if(c=='{')return '}'; if(c=='<')return '>'; if(c=='[')return ']'; if(c=='"')return '"'; if(c=='\'')return '\''; return ' '; } }
VarObject是一个简单javaBean:
package com.luobk.po; /** * * @author LBK * */ public class VarObject { public String getVar() { return var; } public void setVar(String var) //dsfs { this.var = var; } public String getType( ) { return type; } public void setType(String v) { type = v; } // var name private String var; // var type private String type; }
写是写出来了,但是还是有很多问题。 比如对try catch块到底如何处理比较好? 对于简单行(单字符行)的处理的处理怎么样才好?而且,程序本身有bug,有些地方只是做了简单处理,复杂情况下则引发bug。而且,没有考虑对其他的类的影响...
相关推荐
ansys maxwell
matlab基于不确定性可达性优化的自主鲁棒操作.zip
文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。
信息安全课程实验C++实现DES等算法源代码
环境 python >= 3.6 pyahocorasick==1.4.2 requests==2.25.1 gevent==1.4.0 jieba==0.42.1 six==1.15.0 gensim==3.8.3 matplotlib==3.1.3 Flask==1.1.1 numpy==1.16.0 bert4keras==0.9.1 tensorflow==1.14.0 Keras==2.3.1 py2neo==2020.1.1 tqdm==4.42.1 pandas==1.0.1 termcolor==1.1.0 itchat==1.3.10 ahocorasick==0.9 flask_compress==1.9.0 flask_cors==3.0.10 flask_json==0.3.4 GPUtil==1.4.0 pyzmq==22.0.3 scikit_learn==0.24.1 效果展示 为能最简化使用该系统,不需要繁杂的部署各种七七八八的东西,当前版本使用的itchat将问答功能集成到微信做演示,这需要你的微信能登入网页微信才能使用itchat;另外对话上下文并没
一个高品质的音乐共享和流媒体轻量音乐程序网站在线音乐源码,是创建您自己的音乐流媒体网站的最佳方式! 最新版本: 添加插件系统,现在开发人员可以为程序制作插件并在更新后保留您的自定义设置。 固定的2 个以上的小错误。 安装所需:nginx/apache,mysql5.6+,php7+ 搭建说明:看源码内详细说明
实现的金融风控贷款违约预测python源码.zip实现的金融风控贷款违约预测python源码.zip实现的金融风控贷款违约预测python源码.zip实现的金融风控贷款违约预测python源码.zip实现的金融风控贷款违约预测python源码.zip实现的金融风控贷款违约预测python源码.zip实现的金融风控贷款违约预测python源码.zip实现的金融风控贷款违约预测python源码.zip实现的金融风控贷款违约预测python源码.zip实现的金融风控贷款违约预测python源码.zip实现的金融风控贷款违约预测python源码.zip
麦肯锡—xx数码公司发展战略咨询报告.ppt
FT_Prog_v3.12.38.643--FTD USB 工作模式设定及eprom读写
基于sklearn实现线性回归模型对波士顿房价进行预测源码.zip
文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。
文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。
基于相干衍射成像模拟的matlab源码.zip
项目介绍 背景 在当今的数字化时代,远程监控系统已经成为企业和个人必不可少的工具。随着物联网(IoT)技术的发展,监控系统的需求不断增加,不仅仅局限于视频监控,还包括数据监控、设备状态监控等。基于CS(Client-Server)架构的远程监控系统应运而生,旨在提供高效、实时、可靠的监控服务,帮助用户实现远程管理和控制。 目的 基于CS的远程监控系统软件项目旨在为用户提供一个综合性的监控平台,通过该平台,用户可以实时监控各类设备和数据,实现远程控制和管理,提高工作效率,降低运营成本。同时,该系统还可以用于安全防护、生产过程监控等多种场景,具有广泛的应用前景。 模块说明 前端模块 前端模块是用户与系统交互的界面,负责展示监控数据和接收用户指令。前端模块的主要功能包括: 用户登录与认证:通过安全的登录机制,确保只有授权用户才能访问系统。 实时数据展示:以图表、仪表盘等形式展示实时监控数据,包括视频流、传感器数据等。 报警通知:当监控系统检测到异常情况时,前端模块会通过弹窗、声音等方式通知用户。 远程控制:用户可以通过前端界面对设备进行远程控制,例如开关设备、调整参数等。
网课专注度监测预警系统基于yolov5目标检测的网课专注度检测系统源码+模型+pyqt5界面.zip
matlab基于标签歧义的深度标签分布学习.zip
九型人格测试题.144题dr.xls
麦肯锡—xx科技业务流程改造报告.ppt
文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。
1-8