001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 * 017 */ 018package org.apache.bcel.generic; 019 020import org.apache.bcel.Const; 021import org.apache.bcel.Repository; 022import org.apache.bcel.classfile.JavaClass; 023 024/** 025 * Denotes reference such as java.lang.String. 026 * 027 * @version $Id: ObjectType.java 1749603 2016-06-21 20:50:19Z ggregory $ 028 */ 029public class ObjectType extends ReferenceType { 030 031 private final String class_name; // Class name of type 032 033 /** 034 * @since 6.0 035 */ 036 public static ObjectType getInstance(final String class_name) { 037 return new ObjectType(class_name); 038 } 039 040 /** 041 * @param class_name fully qualified class name, e.g. java.lang.String 042 */ 043 public ObjectType(final String class_name) { 044 super(Const.T_REFERENCE, "L" + class_name.replace('.', '/') + ";"); 045 this.class_name = class_name.replace('/', '.'); 046 } 047 048 049 /** @return name of referenced class 050 */ 051 public String getClassName() { 052 return class_name; 053 } 054 055 056 /** @return a hash code value for the object. 057 */ 058 @Override 059 public int hashCode() { 060 return class_name.hashCode(); 061 } 062 063 064 /** @return true if both type objects refer to the same class. 065 */ 066 @Override 067 public boolean equals( final Object type ) { 068 return (type instanceof ObjectType) 069 ? ((ObjectType) type).class_name.equals(class_name) 070 : false; 071 } 072 073 074 /** 075 * If "this" doesn't reference a class, it references an interface 076 * or a non-existant entity. 077 * @deprecated (since 6.0) this method returns an inaccurate result 078 * if the class or interface referenced cannot 079 * be found: use referencesClassExact() instead 080 */ 081 @Deprecated 082 public boolean referencesClass() { 083 try { 084 final JavaClass jc = Repository.lookupClass(class_name); 085 return jc.isClass(); 086 } catch (final ClassNotFoundException e) { 087 return false; 088 } 089 } 090 091 092 /** 093 * If "this" doesn't reference an interface, it references a class 094 * or a non-existant entity. 095 * @deprecated (since 6.0) this method returns an inaccurate result 096 * if the class or interface referenced cannot 097 * be found: use referencesInterfaceExact() instead 098 */ 099 @Deprecated 100 public boolean referencesInterface() { 101 try { 102 final JavaClass jc = Repository.lookupClass(class_name); 103 return !jc.isClass(); 104 } catch (final ClassNotFoundException e) { 105 return false; 106 } 107 } 108 109 110 /** 111 * Return true if this type references a class, 112 * false if it references an interface. 113 * @return true if the type references a class, false if 114 * it references an interface 115 * @throws ClassNotFoundException if the class or interface 116 * referenced by this type can't be found 117 */ 118 public boolean referencesClassExact() throws ClassNotFoundException { 119 final JavaClass jc = Repository.lookupClass(class_name); 120 return jc.isClass(); 121 } 122 123 124 /** 125 * Return true if this type references an interface, 126 * false if it references a class. 127 * @return true if the type references an interface, false if 128 * it references a class 129 * @throws ClassNotFoundException if the class or interface 130 * referenced by this type can't be found 131 */ 132 public boolean referencesInterfaceExact() throws ClassNotFoundException { 133 final JavaClass jc = Repository.lookupClass(class_name); 134 return !jc.isClass(); 135 } 136 137 138 /** 139 * Return true if this type is a subclass of given ObjectType. 140 * @throws ClassNotFoundException if any of this class's superclasses 141 * can't be found 142 */ 143 public boolean subclassOf( final ObjectType superclass ) throws ClassNotFoundException { 144 if (this.referencesInterfaceExact() || superclass.referencesInterfaceExact()) { 145 return false; 146 } 147 return Repository.instanceOf(this.class_name, superclass.class_name); 148 } 149 150 151 /** 152 * Java Virtual Machine Specification edition 2, � 5.4.4 Access Control 153 * @throws ClassNotFoundException if the class referenced by this type 154 * can't be found 155 */ 156 public boolean accessibleTo( final ObjectType accessor ) throws ClassNotFoundException { 157 final JavaClass jc = Repository.lookupClass(class_name); 158 if (jc.isPublic()) { 159 return true; 160 } 161 final JavaClass acc = Repository.lookupClass(accessor.class_name); 162 return acc.getPackageName().equals(jc.getPackageName()); 163 } 164}