| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package java.lang; |
| |
| import java.io.Serializable; |
| |
| /** |
| * A representation of a single stack frame. Arrays of {@code StackTraceElement} |
| * are stored in {@link Throwable} objects to represent the whole state of the |
| * call stack at the time a {@code Throwable} gets thrown. |
| * |
| * @see Throwable#getStackTrace() |
| */ |
| public final class StackTraceElement implements Serializable { |
| |
| private static final long serialVersionUID = 6992337162326171013L; |
| |
| private static final int NATIVE_LINE_NUMBER = -2; |
| |
| String declaringClass; |
| |
| String methodName; |
| |
| String fileName; |
| |
| int lineNumber; |
| |
| /** |
| * Constructs a new {@code StackTraceElement} for a specified execution |
| * point. |
| * |
| * @param cls |
| * the fully qualified name of the class where execution is at. |
| * @param method |
| * the name of the method where execution is at. |
| * @param file |
| * The name of the file where execution is at or {@code null}. |
| * @param line |
| * the line of the file where execution is at, a negative number |
| * if unknown or {@code -2} if the execution is in a native |
| * method. |
| * @throws NullPointerException |
| * if {@code cls} or {@code method} is {@code null}. |
| */ |
| public StackTraceElement(String cls, String method, String file, int line) { |
| if (cls == null) { |
| throw new NullPointerException("cls == null"); |
| } else if (method == null) { |
| throw new NullPointerException("method == null"); |
| } |
| declaringClass = cls; |
| methodName = method; |
| fileName = file; |
| lineNumber = line; |
| } |
| |
| /** |
| * <p> |
| * Private, nullary constructor for VM use only. |
| * </p> |
| */ |
| private StackTraceElement() { |
| } |
| |
| /** |
| * Compares this instance with the specified object and indicates if they |
| * are equal. In order to be equal, the following conditions must be |
| * fulfilled: |
| * <ul> |
| * <li>{@code obj} must be a stack trace element,</li> |
| * <li>the method names of this stack trace element and of {@code obj} must |
| * not be {@code null},</li> |
| * <li>the class, method and file names as well as the line number of this |
| * stack trace element and of {@code obj} must be equal.</li> |
| * </ul> |
| * |
| * @param obj |
| * the object to compare this instance with. |
| * @return {@code true} if the specified object is equal to this |
| * {@code StackTraceElement}; {@code false} otherwise. |
| * @see #hashCode |
| */ |
| @Override |
| public boolean equals(Object obj) { |
| if (!(obj instanceof StackTraceElement)) { |
| return false; |
| } |
| StackTraceElement castObj = (StackTraceElement) obj; |
| |
| /* |
| * Unknown methods are never equal to anything (not strictly to spec, |
| * but spec does not allow null method/class names) |
| */ |
| if ((methodName == null) || (castObj.methodName == null)) { |
| return false; |
| } |
| |
| if (!getMethodName().equals(castObj.getMethodName())) { |
| return false; |
| } |
| if (!getClassName().equals(castObj.getClassName())) { |
| return false; |
| } |
| String localFileName = getFileName(); |
| if (localFileName == null) { |
| if (castObj.getFileName() != null) { |
| return false; |
| } |
| } else { |
| if (!localFileName.equals(castObj.getFileName())) { |
| return false; |
| } |
| } |
| if (getLineNumber() != castObj.getLineNumber()) { |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /** |
| * Returns the fully qualified name of the class belonging to this |
| * {@code StackTraceElement}. |
| * |
| * @return the fully qualified type name of the class |
| */ |
| public String getClassName() { |
| return (declaringClass == null) ? "<unknown class>" : declaringClass; |
| } |
| |
| /** |
| * Returns the name of the Java source file containing class belonging to |
| * this {@code StackTraceElement}. |
| * |
| * @return the name of the file, or {@code null} if this information is not |
| * available. |
| */ |
| public String getFileName() { |
| return fileName; |
| } |
| |
| /** |
| * Returns the line number in the source for the class belonging to this |
| * {@code StackTraceElement}. |
| * |
| * @return the line number, or a negative number if this information is not |
| * available. |
| */ |
| public int getLineNumber() { |
| return lineNumber; |
| } |
| |
| /** |
| * Returns the name of the method belonging to this {@code |
| * StackTraceElement}. |
| * |
| * @return the name of the method, or "<unknown method>" if this information |
| * is not available. |
| */ |
| public String getMethodName() { |
| return (methodName == null) ? "<unknown method>" : methodName; |
| } |
| |
| @Override |
| public int hashCode() { |
| /* |
| * Either both methodName and declaringClass are null, or neither are |
| * null. |
| */ |
| if (methodName == null) { |
| // all unknown methods hash the same |
| return 0; |
| } |
| // declaringClass never null if methodName is non-null |
| return methodName.hashCode() ^ declaringClass.hashCode(); |
| } |
| |
| /** |
| * Indicates if the method name returned by {@link #getMethodName()} is |
| * implemented as a native method. |
| * |
| * @return {@code true} if the method in which this stack trace element is |
| * executing is a native method; {@code false} otherwise. |
| */ |
| public boolean isNativeMethod() { |
| return lineNumber == NATIVE_LINE_NUMBER; |
| } |
| |
| @Override |
| public String toString() { |
| StringBuilder buf = new StringBuilder(80); |
| |
| buf.append(getClassName()); |
| buf.append('.'); |
| buf.append(getMethodName()); |
| |
| if (isNativeMethod()) { |
| buf.append("(Native Method)"); |
| } else { |
| String fName = getFileName(); |
| |
| if (fName == null) { |
| buf.append("(Unknown Source)"); |
| } else { |
| int lineNum = getLineNumber(); |
| |
| buf.append('('); |
| buf.append(fName); |
| if (lineNum >= 0) { |
| buf.append(':'); |
| buf.append(lineNum); |
| } |
| buf.append(')'); |
| } |
| } |
| return buf.toString(); |
| } |
| } |