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

📄 serializableidiom.java

📁 一个查找java程序里bug的程序的源代码,该程序本身也是java写的,对提高java编程水平很有用
💻 JAVA
字号:
/* * FindBugs - Find bugs in Java programs * Copyright (C) 2003,2004 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.*;import edu.umd.cs.findbugs.BugInstance;import edu.umd.cs.findbugs.BugReporter;import edu.umd.cs.findbugs.Detector;import edu.umd.cs.findbugs.ba.AnalysisContext;import edu.umd.cs.findbugs.ba.ClassContext;import edu.umd.cs.findbugs.visitclass.Constants2;import edu.umd.cs.findbugs.visitclass.PreorderVisitor;import org.apache.bcel.Repository;import org.apache.bcel.classfile.*;import java.util.regex.Pattern;public class SerializableIdiom extends PreorderVisitor        implements Detector, Constants2 {	boolean sawSerialVersionUID;	boolean isSerializable, implementsSerializableDirectly;	boolean isExternalizable;	boolean isGUIClass;	boolean foundSynthetic;	boolean foundSynchronizedMethods;	boolean writeObjectIsSynchronized;	private BugReporter bugReporter;	//private AnalysisContext analysisContext;	boolean isAbstract;	private List<BugInstance> fieldWarningList = new LinkedList<BugInstance>();	private boolean sawReadExternal;	private boolean sawWriteExternal;	private boolean sawReadObject;	private boolean sawWriteObject;	private boolean superClassImplementsSerializable;	private boolean hasPublicVoidConstructor;	private boolean superClassHasVoidConstructor;	private boolean directlyImplementsExternalizable;	//private boolean isRemote;	public SerializableIdiom(BugReporter bugReporter) {		this.bugReporter = bugReporter;	}	public void setAnalysisContext(AnalysisContext analysisContext) {		//this.analysisContext = analysisContext;	}	public void visitClassContext(ClassContext classContext) {		classContext.getJavaClass().accept(this);		flush();	}	private void flush() {		if (!isAbstract &&		        !((sawReadExternal && sawWriteExternal) || (sawReadObject && sawWriteObject))) {			Iterator<BugInstance> i = fieldWarningList.iterator();			while (i.hasNext())				bugReporter.reportBug(i.next());		}		fieldWarningList.clear();	}	public void report() {	}	static Pattern anonymousInnerClassNamePattern =			Pattern.compile(".+\\$\\d+");	boolean isAnonymousInnerClass;	public void visit(JavaClass obj) {		int flags = obj.getAccessFlags();		isAbstract = (flags & ACC_ABSTRACT) != 0		        || (flags & ACC_INTERFACE) != 0;		isAnonymousInnerClass 		  = anonymousInnerClassNamePattern			.matcher(getClassName()).matches();						sawSerialVersionUID = false;		isSerializable = implementsSerializableDirectly = false;		isExternalizable = false;		directlyImplementsExternalizable = false;		isGUIClass = false;				//isRemote = false;		// Does this class directly implement Serializable?		String[] interface_names = obj.getInterfaceNames();		for (int i = 0; i < interface_names.length; i++) {			if (interface_names[i].equals("java.io.Externalizable")) {				directlyImplementsExternalizable = true;				isExternalizable = true;				// System.out.println("Directly implements Externalizable: " + betterClassName);			} else if (interface_names[i].equals("java.io.Serializable")) {				implementsSerializableDirectly = true;				isSerializable = true;				break;			}		}		// Does this class indirectly implement Serializable?		if (!isSerializable) {			try {				if (Repository.instanceOf(obj, "java.io.Externalizable"))					isExternalizable = true;				if (Repository.instanceOf(obj, "java.io.Serializable"))					isSerializable = true;/*	        if (Repository.instanceOf(obj,"java.rmi.Remote")) {		    isRemote = true;		    }*/			} catch (ClassNotFoundException e) {				bugReporter.reportMissingClass(e);			}		}		hasPublicVoidConstructor = false;		superClassHasVoidConstructor = true;		superClassImplementsSerializable = isSerializable && !implementsSerializableDirectly;		try {			JavaClass superClass = obj.getSuperClass();			if (superClass != null) {				Method[] superClassMethods = superClass.getMethods();				superClassImplementsSerializable = Repository.instanceOf(superClass,				        "java.io.Serializable");				superClassHasVoidConstructor = false;				for (int i = 0; i < superClassMethods.length; i++) {					Method m = superClassMethods[i];					/*					if (!m.isPrivate())					System.out.println("Supercase of " + className						+ " has an accessible method named " + m.getName()						+ " with sig " + m.getSignature());					*/					if (m.getName().equals("<init>")					        && m.getSignature().equals("()V")					        && !m.isPrivate()					) {						// System.out.println("  super has void constructor");						superClassHasVoidConstructor = true;						break;					}				}			}		} catch (ClassNotFoundException e) {			bugReporter.reportMissingClass(e);		}		// Is this a GUI  or other class that is rarely serialized?		try {			isGUIClass = 			 Repository.instanceOf(obj, "java.lang.Throwable")			|| Repository.instanceOf(obj, "java.awt.Component")			|| Repository.implementationOf(obj, "java.awt.event.ActionListener")			|| Repository.implementationOf(obj, "java.util.EventListener")			;		} catch (ClassNotFoundException e) {			bugReporter.reportMissingClass(e);		}		foundSynthetic = false;		foundSynchronizedMethods = false;		writeObjectIsSynchronized = false;		sawReadExternal = sawWriteExternal = sawReadObject = sawWriteObject = false;	}	public void visitAfter(JavaClass obj) {		if (false) {			System.out.println(getDottedClassName());			System.out.println("  hasPublicVoidConstructor: " + hasPublicVoidConstructor);			System.out.println("  superClassHasVoidConstructor: " + superClassHasVoidConstructor);			System.out.println("  isExternalizable: " + isExternalizable);			System.out.println("  isSerializable: " + isSerializable);			System.out.println("  isAbstract: " + isAbstract);			System.out.println("  superClassImplementsSerializable: " + superClassImplementsSerializable);		}		if (isSerializable && !isExternalizable		        && !superClassHasVoidConstructor		        && !superClassImplementsSerializable)			bugReporter.reportBug(new BugInstance(this, "SE_NO_SUITABLE_CONSTRUCTOR",			        (implementsSerializableDirectly || sawSerialVersionUID)			        ? HIGH_PRIORITY : NORMAL_PRIORITY)			        .addClass(getThisClass().getClassName()));		// Downgrade class-level warnings if it's a GUI class.		int priority = isGUIClass ? LOW_PRIORITY : NORMAL_PRIORITY;		if (obj.getClassName().endsWith("_Stub")) priority++;		if (isExternalizable && !hasPublicVoidConstructor && !isAbstract)			bugReporter.reportBug(new BugInstance(this, "SE_NO_SUITABLE_CONSTRUCTOR_FOR_EXTERNALIZATION",			        directlyImplementsExternalizable ?			        HIGH_PRIORITY : NORMAL_PRIORITY)			        .addClass(getThisClass().getClassName()));		if (foundSynthetic 			&& !isAnonymousInnerClass 			&& !isExternalizable && !isGUIClass		        && isSerializable && !isAbstract && !sawSerialVersionUID)			bugReporter.reportBug(new BugInstance(this, "SE_NO_SERIALVERSIONID", priority).addClass(this));		if (writeObjectIsSynchronized && !foundSynchronizedMethods)			bugReporter.reportBug(new BugInstance(this, "WS_WRITEOBJECT_SYNC", LOW_PRIORITY).addClass(this));	}	public void visit(Method obj) {		int accessFlags = obj.getAccessFlags();		boolean isSynchronized = (accessFlags & ACC_SYNCHRONIZED) != 0;		if (getMethodName().equals("<init>") && getMethodSig().equals("()V")		        && (accessFlags & ACC_PUBLIC) != 0		)			hasPublicVoidConstructor = true;		if (!getMethodName().equals("<init>")		        && isSynthetic(obj))			foundSynthetic = true;		// System.out.println(methodName + isSynchronized);		if (getMethodName().equals("readExternal")		        && getMethodSig().equals("(Ljava/io/ObjectInput;)V")) {			sawReadExternal = true;			if (false && !obj.isPrivate())				System.out.println("Non-private readExternal method in: " + getDottedClassName());		} else if (getMethodName().equals("writeExternal")		        && getMethodSig().equals("(Ljava/io/Objectoutput;)V")) {			sawWriteExternal = true;			if (false && !obj.isPrivate())				System.out.println("Non-private writeExternal method in: " + getDottedClassName());		} else if (getMethodName().equals("readObject")		        && getMethodSig().equals("(Ljava/io/ObjectInputStream;)V")		        && isSerializable) {			sawReadObject = true;			if (false && !obj.isPrivate())				System.out.println("Non-private readObject method in: " + getDottedClassName());		} else if (getMethodName().equals("writeObject")		        && getMethodSig().equals("(Ljava/io/ObjectOutputStream;)V")		        && isSerializable) {			sawReadObject = true;			if (false && !obj.isPrivate())				System.out.println("Non-private writeObject method in: " + getDottedClassName());		}		if (!isSynchronized) return;		if (getMethodName().equals("readObject") &&		        getMethodSig().equals("(Ljava/io/ObjectInputStream;)V") &&		        isSerializable)			bugReporter.reportBug(new BugInstance(this, "RS_READOBJECT_SYNC", NORMAL_PRIORITY).addClass(this));		else if (getMethodName().equals("writeObject")		        && getMethodSig().equals("(Ljava/io/ObjectOutputStream;)V")		        && isSerializable)			writeObjectIsSynchronized = true;		else			foundSynchronizedMethods = true;	}	boolean isSynthetic(FieldOrMethod obj) {		Attribute[] a = obj.getAttributes();		for (int i = 0; i < a.length; i++)			if (a[i] instanceof Synthetic) return true;		return false;	}	public void visit(Field obj) {		int flags = obj.getAccessFlags();		if (getClassName().indexOf("ObjectStreamClass") == -1		        && isSerializable		        && !isExternalizable		        && getFieldSig().indexOf("L") >= 0 && !obj.isTransient() && !obj.isStatic()) {			try {				String fieldTypeClassName = getFieldSig().substring(getFieldSig().indexOf("L") + 1, getFieldSig().length() - 1).replace('/', '.');				JavaClass fieldTypeClass = Repository.lookupClass(fieldTypeClassName);				if (!fieldTypeClassName.equals("java.lang.Object") &&				        !(Repository.instanceOf(fieldTypeClass, "java.io.Serializable")				        || Repository.instanceOf(fieldTypeClass, "java.io.Externalizable"))) {					// Priority is LOW for GUI classes (unless explicitly marked Serializable),					// HIGH if the class directly implements Serializable,					// NORMAL otherwise.					int priority = NORMAL_PRIORITY;					if (implementsSerializableDirectly || sawSerialVersionUID)						priority--;					if (isGUIClass)						priority++;					// Lower the priority for fields which are of an interface					// or abstract type, since the user may know that all subtypes of					// the interface will be Serializable.					if (fieldTypeClass.isInterface()					        || fieldTypeClass.isAbstract()) {						priority = Math.max(LOW_PRIORITY, priority + 1);						if (Repository.instanceOf(fieldTypeClass,						        "java.util.Collection"))							return;					}					// Report is queued until after the entire class has been seen.					fieldWarningList.add(new BugInstance(this, "SE_BAD_FIELD", priority)					        .addClass(getThisClass().getClassName())					        .addField(getDottedClassName(), obj.getName(), getFieldSig(), false));				}			} catch (ClassNotFoundException e) {				bugReporter.reportMissingClass(e);			}		}		if (!getFieldName().startsWith("this")		        && isSynthetic(obj))			foundSynthetic = true;		if (!getFieldName().equals("serialVersionUID")) return;		int mask = ACC_STATIC | ACC_FINAL;		if (!getFieldSig().equals("I")		        && !getFieldSig().equals("J"))			return;		if ((flags & mask) == mask		        && getFieldSig().equals("I")) {			bugReporter.reportBug(new BugInstance(this, "SE_NONLONG_SERIALVERSIONID", LOW_PRIORITY)			        .addClass(this)			        .addVisitedField(this));			sawSerialVersionUID = true;			return;		} else if ((flags & ACC_STATIC) == 0) {			bugReporter.reportBug(new BugInstance(this, "SE_NONSTATIC_SERIALVERSIONID", NORMAL_PRIORITY)			        .addClass(this)			        .addVisitedField(this));			return;		} else if ((flags & ACC_FINAL) == 0) {			bugReporter.reportBug(new BugInstance(this, "SE_NONFINAL_SERIALVERSIONID", NORMAL_PRIORITY)			        .addClass(this)			        .addVisitedField(this));			return;		}		sawSerialVersionUID = true;	}}

⌨️ 快捷键说明

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