1 /* Class.java -- Representation of a Java class.
2 Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004
3 Free Software Foundation
5 This file is part of GNU Classpath.
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING. If not, write to the
19 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 Linking this library statically or dynamically with other modules is
23 making a combined work based on this library. Thus, the terms and
24 conditions of the GNU General Public License cover the whole
27 As a special exception, the copyright holders of this library give you
28 permission to link this library with independent modules to produce an
29 executable, regardless of the license terms of these independent
30 modules, and to copy and distribute the resulting executable under
31 terms of your choice, provided that you also meet, for each linked
32 independent module, the terms and conditions of the license of that
33 module. An independent module is a module which is not derived from
34 or based on this library. If you modify this library, you may extend
35 this exception to your version of the library, but you are not
36 obligated to do so. If you do not wish to do so, delete this
37 exception statement from your version. */
41 import java.io.Serializable;
42 import java.io.InputStream;
43 import java.lang.reflect.*;
44 import java.security.*;
45 import java.util.Arrays;
46 import java.util.HashSet;
49 * @author Tom Tromey <tromey@cygnus.com>
50 * @date October 1, 1998
53 /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
54 * "The Java Language Specification", ISBN 0-201-63451-1
55 * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
56 * plus gcj compiler sources (to determine object layout)
57 * Status: Sufficient for our purposes, but some methods missing
58 * and some not implemented.
61 public final class Class implements Serializable
63 public static native Class forName (String className)
64 throws ClassNotFoundException;
66 public static native Class forName (String className, boolean initialize,
68 throws ClassNotFoundException;
69 public native Class[] getClasses ();
70 public native ClassLoader getClassLoader ();
71 public native Class getComponentType ();
73 public native Constructor getConstructor (Class[] parameterTypes)
74 throws NoSuchMethodException, SecurityException;
76 // This is used to implement getConstructors and
77 // getDeclaredConstructors.
78 private native Constructor[] _getConstructors (boolean declared)
79 throws SecurityException;
81 public Constructor[] getConstructors () throws SecurityException
83 return _getConstructors (false);
86 public native Constructor getDeclaredConstructor (Class[] parameterTypes)
87 throws NoSuchMethodException, SecurityException;
89 public native Class[] getDeclaredClasses () throws SecurityException;
91 public Constructor[] getDeclaredConstructors () throws SecurityException
93 return _getConstructors (true);
96 public native Field getDeclaredField (String fieldName)
97 throws NoSuchFieldException, SecurityException;
100 * Get all the declared fields in this class, but not those inherited from
101 * superclasses. This returns an array of length 0 if there are no fields,
102 * including for primitive types. This does not return the implicit length
103 * field of arrays. A security check may be performed, with
104 * <code>checkMemberAccess(this, Member.DECLARED)</code> as well as
105 * <code>checkPackageAccess</code> both having to succeed.
107 * @return all declared fields in this class
108 * @throws SecurityException if the security check fails
111 public Field[] getDeclaredFields()
113 memberAccessCheck(Member.DECLARED);
114 return getDeclaredFields(false);
117 native Field[] getDeclaredFields (boolean publicOnly);
119 private native Method _getDeclaredMethod (String methodName,
120 Class[] parameterTypes);
122 public Method getDeclaredMethod (String methodName, Class[] parameterTypes)
123 throws NoSuchMethodException, SecurityException
125 memberAccessCheck(Member.DECLARED);
127 if ("<init>".equals(methodName) || "<clinit>".equals(methodName))
128 throw new NoSuchMethodException(methodName);
130 Method m = _getDeclaredMethod(methodName, parameterTypes);
132 throw new NoSuchMethodException (methodName);
136 public native Method[] getDeclaredMethods () throws SecurityException;
138 // This is marked as unimplemented in the JCL book.
139 public native Class getDeclaringClass ();
141 private native Field getField (String fieldName, int hash)
142 throws NoSuchFieldException, SecurityException;
144 public Field getField (String fieldName)
145 throws NoSuchFieldException, SecurityException
147 memberAccessCheck (Member.PUBLIC);
148 Field fld = getField(fieldName, fieldName.hashCode());
150 throw new NoSuchFieldException(fieldName);
155 * Get all the public fields declared in this class or inherited from
156 * superclasses. This returns an array of length 0 if there are no fields,
157 * including for primitive types. This does not return the implicit length
158 * field of arrays. A security check may be performed, with
159 * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as
160 * <code>checkPackageAccess</code> both having to succeed.
162 * @return all public fields in this class
163 * @throws SecurityException if the security check fails
166 public Field[] getFields()
168 memberAccessCheck(Member.PUBLIC);
169 return internalGetFields();
173 * Like <code>getFields()</code> but without the security checks.
175 private Field[] internalGetFields()
177 HashSet set = new HashSet();
178 set.addAll(Arrays.asList(getDeclaredFields(true)));
179 Class[] interfaces = getInterfaces();
180 for (int i = 0; i < interfaces.length; i++)
181 set.addAll(Arrays.asList(interfaces[i].internalGetFields()));
182 Class superClass = getSuperclass();
183 if (superClass != null)
184 set.addAll(Arrays.asList(superClass.internalGetFields()));
185 return (Field[])set.toArray(new Field[set.size()]);
189 * Returns the <code>Package</code> in which this class is defined
190 * Returns null when this information is not available from the
191 * classloader of this class or when the classloader of this class
196 public Package getPackage()
198 ClassLoader cl = getClassLoader();
201 String name = getName();
203 int idx = name.lastIndexOf('.');
205 pkg = name.substring(0, idx);
206 return cl.getPackage(pkg);
212 public native Class[] getInterfaces ();
214 private final native void getSignature (StringBuffer buffer);
215 private static final native String getSignature (Class[] parameterTypes,
216 boolean is_construtor);
218 public native Method _getMethod (String methodName, Class[] parameterTypes);
220 public Method getMethod (String methodName, Class[] parameterTypes)
221 throws NoSuchMethodException, SecurityException
223 memberAccessCheck(Member.PUBLIC);
225 if ("<init>".equals(methodName) || "<clinit>".equals(methodName))
226 throw new NoSuchMethodException(methodName);
228 Method m = _getMethod(methodName, parameterTypes);
230 throw new NoSuchMethodException (methodName);
234 private native int _getMethods (Method[] result, int offset);
235 public native Method[] getMethods () throws SecurityException;
237 public native int getModifiers ();
238 public native String getName ();
240 public java.net.URL getResource (String resourceName)
242 String name = resourcePath (resourceName);
243 ClassLoader loader = getClassLoader ();
245 return ClassLoader.getSystemResource (name);
247 return loader.getResource (name);
250 public java.io.InputStream getResourceAsStream (String resourceName)
252 String name = resourcePath (resourceName);
253 ClassLoader loader = getClassLoader ();
255 return ClassLoader.getSystemResourceAsStream (name);
257 return loader.getResourceAsStream (name);
260 private String resourcePath (String resourceName)
262 if (resourceName.startsWith ("/"))
263 return resourceName.substring (1);
267 c = c.getComponentType ();
269 String packageName = c.getName ().replace ('.', '/');
270 int end = packageName.lastIndexOf ('/');
274 return packageName.substring (0, end+1) + resourceName;
277 public native Object[] getSigners ();
278 native void setSigners(Object[] signers);
280 public native Class getSuperclass ();
281 public native boolean isArray ();
282 public native boolean isAssignableFrom (Class cls);
283 public native boolean isInstance (Object obj);
284 public native boolean isInterface ();
285 public native boolean isPrimitive ();
286 public native Object newInstance ()
287 throws InstantiationException, IllegalAccessException;
289 // We need a native method to retrieve the protection domain, because we
290 // can't add fields to java.lang.Class that are accessible from Java.
291 private native ProtectionDomain getProtectionDomain0();
294 * Returns the protection domain of this class. If the classloader
295 * did not record the protection domain when creating this class
296 * the unknown protection domain is returned which has a <code>null</code>
297 * code source and all permissions.
299 * @exception SecurityException if a security manager exists and the caller
300 * does not have <code>RuntimePermission("getProtectionDomain")</code>.
304 public ProtectionDomain getProtectionDomain()
306 SecurityManager sm = System.getSecurityManager();
308 sm.checkPermission(VMClassLoader.protectionDomainPermission);
310 ProtectionDomain protectionDomain = getProtectionDomain0();
312 if (protectionDomain == null)
313 return VMClassLoader.unknownProtectionDomain;
315 return protectionDomain;
318 public String toString ()
322 return (isInterface () ? "interface " : "class ") + getName ();
326 * Returns the desired assertion status of this class, if it were to be
327 * initialized at this moment. The class assertion status, if set, is
328 * returned; the backup is the default package status; then if there is
329 * a class loader, that default is returned; and finally the system default
330 * is returned. This method seldom needs calling in user code, but exists
331 * for compilers to implement the assert statement. Note that there is no
332 * guarantee that the result of this method matches the class's actual
335 * @return the desired assertion status
336 * @see ClassLoader#setClassAssertionStatus(String, boolean)
337 * @see ClassLoader#setPackageAssertionStatus(String, boolean)
338 * @see ClassLoader#setDefaultAssertionStatus(boolean)
341 public boolean desiredAssertionStatus()
343 ClassLoader c = getClassLoader();
346 return VMClassLoader.defaultAssertionStatus();
347 if (c.classAssertionStatus != null)
350 status = c.classAssertionStatus.get(getName());
352 return status.equals(Boolean.TRUE);
356 status = ClassLoader.systemClassAssertionStatus.get(getName());
358 return status.equals(Boolean.TRUE);
360 if (c.packageAssertionStatus != null)
363 String name = getPackagePortion(getName());
365 status = c.packageAssertionStatus.get(null);
369 status = c.packageAssertionStatus.get(name);
370 name = getPackagePortion(name);
372 while (! "".equals(name) && status == null);
374 return status.equals(Boolean.TRUE);
378 String name = getPackagePortion(getName());
380 status = ClassLoader.systemPackageAssertionStatus.get(null);
384 status = ClassLoader.systemPackageAssertionStatus.get(name);
385 name = getPackagePortion(name);
387 while (! "".equals(name) && status == null);
389 return status.equals(Boolean.TRUE);
391 return c.defaultAssertionStatus;
394 // Don't allow new classes to be made.
399 // Initialize the class.
400 private native void initializeClass ();
403 protected native void finalize () throws Throwable;
406 * Strip the last portion of the name (after the last dot).
408 * @param name the name to get package of
409 * @return the package name, or "" if no package
411 private static String getPackagePortion(String name)
413 int lastInd = name.lastIndexOf('.');
416 return name.substring(0, lastInd);
420 * Perform security checks common to all of the methods that
421 * get members of this Class.
423 private void memberAccessCheck(int which)
425 SecurityManager sm = System.getSecurityManager();
428 sm.checkMemberAccess(this, which);
429 Package pkg = getPackage();
431 sm.checkPackageAccess(pkg.getName());