⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 findhemismatch.java

📁 A static analysis tool to find bugs in Java programs
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * FindBugs - Find bugs in Java programs * Copyright (C) 2003-2005 University of Maryland *  * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. *  * This library 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. *  * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */package edu.umd.cs.findbugs.detect;import java.util.HashMap;import java.util.HashSet;import java.util.Map;import java.util.regex.Matcher;import java.util.regex.Pattern;import org.apache.bcel.Repository;import org.apache.bcel.classfile.Code;import org.apache.bcel.classfile.Field;import org.apache.bcel.classfile.JavaClass;import org.apache.bcel.classfile.Method;import org.apache.bcel.classfile.Signature;import edu.umd.cs.findbugs.BugInstance;import edu.umd.cs.findbugs.BugReporter;import edu.umd.cs.findbugs.BytecodeScanningDetector;import edu.umd.cs.findbugs.Lookup;import edu.umd.cs.findbugs.MethodAnnotation;import edu.umd.cs.findbugs.OpcodeStack;import edu.umd.cs.findbugs.Priorities;import edu.umd.cs.findbugs.StatelessDetector;import edu.umd.cs.findbugs.TypeAnnotation;import edu.umd.cs.findbugs.annotations.CheckForNull;import edu.umd.cs.findbugs.ba.AnalysisContext;public class FindHEmismatch extends BytecodeScanningDetector implements		StatelessDetector {	boolean hasFields = false;	boolean visibleOutsidePackage = false;	boolean hasHashCode = false;	boolean hasEqualsObject = false;	boolean hashCodeIsAbstract = false;	boolean equalsObjectIsAbstract = false;	boolean equalsMethodIsInstanceOfEquals = false;	boolean hasCompareToObject = false;	boolean hasEqualsSelf = false;	boolean hasCompareToSelf = false;	boolean extendsObject = false;	MethodAnnotation equalsMethod = null;	MethodAnnotation compareToMethod = null;	MethodAnnotation compareToObjectMethod = null;	MethodAnnotation compareToSelfMethod = null;	MethodAnnotation hashCodeMethod = null;	 HashSet<String> nonHashableClasses = new HashSet<String>();	OpcodeStack stack = new OpcodeStack();	public  boolean isHashableClassName(String dottedClassName) {		return !nonHashableClasses.contains(dottedClassName);	}	Map<String, BugInstance> potentialBugs = new HashMap<String, BugInstance>();	private BugReporter bugReporter;	public FindHEmismatch(BugReporter bugReporter) {		this.bugReporter = bugReporter;	}	@Override	public void visitAfter(JavaClass obj) {		if (!obj.isClass())			return;		if (getDottedClassName().equals("java.lang.Object"))			return;		int accessFlags = obj.getAccessFlags();		if ((accessFlags & ACC_INTERFACE) != 0)			return;		visibleOutsidePackage = obj.isPublic() || obj.isProtected();		String whereEqual = getDottedClassName();		boolean classThatDefinesEqualsIsAbstract = false;		boolean inheritedHashCodeIsFinal = false;		boolean inheritedEqualsIsFinal = false;		boolean inheritedEqualsIsAbstract = false;		if (!hasEqualsObject) {			JavaClass we = Lookup.findSuperImplementor(obj, "equals",					"(Ljava/lang/Object;)Z", bugReporter);			if (we == null) {				whereEqual = "java.lang.Object";			} else {				whereEqual = we.getClassName();				classThatDefinesEqualsIsAbstract = we.isAbstract();				Method m = findMethod(we, "equals", "(Ljava/lang/Object;)Z");				if (m != null && m.isFinal())					inheritedEqualsIsFinal = true;				if (m != null && m.isAbstract())					inheritedEqualsIsAbstract = true;			}		}		boolean usesDefaultEquals = whereEqual.equals("java.lang.Object");		String whereHashCode = getDottedClassName();		if (!hasHashCode) {			JavaClass wh = Lookup.findSuperImplementor(obj, "hashCode", "()I",					bugReporter);			if (wh == null) {				whereHashCode = "java.lang.Object";			} else {				whereHashCode = wh.getClassName();				Method m = findMethod(wh, "hashCode", "()I");				if (m != null && m.isFinal())					inheritedHashCodeIsFinal = true;			}		}		boolean usesDefaultHashCode = whereHashCode.equals("java.lang.Object");		if (false && (usesDefaultEquals || usesDefaultHashCode)) {			try {				if (Repository.implementationOf(obj, "java/util/Set")						|| Repository.implementationOf(obj, "java/util/List")						|| Repository.implementationOf(obj, "java/util/Map")) {					// System.out.println(getDottedClassName() + " uses default					// hashCode or equals");				}			} catch (ClassNotFoundException e) {				// e.printStackTrace();			}		}		if (!hasEqualsObject && hasEqualsSelf) {			if (usesDefaultEquals) {				int priority = HIGH_PRIORITY;				if (usesDefaultHashCode || obj.isAbstract())					priority++;				if (!visibleOutsidePackage)					priority++;				String bugPattern = "EQ_SELF_USE_OBJECT";				BugInstance bug = new BugInstance(this, bugPattern,						priority).addClass(getDottedClassName());				if (equalsMethod != null)					bug.addMethod(equalsMethod);				bugReporter.reportBug(bug);			} else {				int priority = NORMAL_PRIORITY;				if (hasFields)					priority--;				if (obj.isAbstract())					priority++;				String bugPattern = "EQ_SELF_NO_OBJECT";				String superclassName = obj.getSuperclassName();				if (superclassName.equals("java.lang.Enum")) {					bugPattern = "EQ_DONT_DEFINE_EQUALS_FOR_ENUM";					priority = HIGH_PRIORITY;				}				BugInstance bug = new BugInstance(this, bugPattern,						priority).addClass(getDottedClassName());				if (equalsMethod != null)					bug.addMethod(equalsMethod);				bugReporter.reportBug(bug);			}		}//		 System.out.println("Class " + getDottedClassName());//		  System.out.println("usesDefaultEquals: " + usesDefaultEquals);//		  System.out.println("hasHashCode: : " + hasHashCode);//		  System.out.println("usesDefaultHashCode: " + usesDefaultHashCode);//		  System.out.println("hasEquals: : " + hasEqualsObject);//		  System.out.println("hasCompareToObject: : " + hasCompareToObject);//		  System.out.println("hasCompareToSelf: : " + hasCompareToSelf);		if ((hasCompareToObject || hasCompareToSelf) && usesDefaultEquals) {			BugInstance bug = new BugInstance(this, "EQ_COMPARETO_USE_OBJECT_EQUALS",					obj.isAbstract() ? Priorities.LOW_PRIORITY : Priorities.NORMAL_PRIORITY).addClass(this);			if (compareToSelfMethod != null) bug.addMethod(compareToSelfMethod);			else bug.addMethod(compareToObjectMethod);			bugReporter.reportBug(bug);		}		if (!hasCompareToObject && hasCompareToSelf) {			if (!extendsObject)				bugReporter.reportBug(new BugInstance(this,						"CO_SELF_NO_OBJECT", NORMAL_PRIORITY).addClass(						getDottedClassName()).addMethod(compareToMethod));		}		// if (!hasFields) return;		if (hasHashCode && !hashCodeIsAbstract				&& !(hasEqualsObject || hasEqualsSelf)) {			int priority = LOW_PRIORITY;			if (usesDefaultEquals)				bugReporter.reportBug(new BugInstance(this,						"HE_HASHCODE_USE_OBJECT_EQUALS", priority).addClass(						getDottedClassName()).addMethod(hashCodeMethod));			else if (!inheritedEqualsIsFinal)				bugReporter.reportBug(new BugInstance(this,						"HE_HASHCODE_NO_EQUALS", priority).addClass(						getDottedClassName()).addMethod(hashCodeMethod));		}		if (!hasHashCode				&& (hasEqualsObject && !equalsObjectIsAbstract || hasEqualsSelf)) {			if (usesDefaultHashCode) {				int priority = HIGH_PRIORITY;				if (equalsMethodIsInstanceOfEquals)					priority += 2;				else if (obj.isAbstract() || !hasEqualsObject)					priority++;				if (priority == HIGH_PRIORITY)					nonHashableClasses.add(getDottedClassName());				if (!visibleOutsidePackage) {					priority++;				}				BugInstance bug = new BugInstance(this,						"HE_EQUALS_USE_HASHCODE", priority)						.addClass(getDottedClassName());				if (equalsMethod != null)					bug.addMethod(equalsMethod);				bugReporter.reportBug(bug);			} else if (!inheritedHashCodeIsFinal					&& !whereHashCode.startsWith("java.util.Abstract")) {				int priority = LOW_PRIORITY;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -