1 // Class.java - Representation of a Java class.
3 /* Copyright (C) 1998, 1999, 2000, 2002, 2003 Free Software Foundation
5 This file is part of libgcj.
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
12 import java.io.Serializable;
13 import java.io.InputStream;
14 import java.lang.reflect.*;
15 import java.security.*;
18 * @author Tom Tromey <tromey@cygnus.com>
19 * @date October 1, 1998
22 /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
23 * "The Java Language Specification", ISBN 0-201-63451-1
24 * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
25 * plus gcj compiler sources (to determine object layout)
26 * Status: Sufficient for our purposes, but some methods missing
27 * and some not implemented.
30 public final class Class implements Serializable
32 public static native Class forName (String className)
33 throws ClassNotFoundException;
35 public static native Class forName (String className, boolean initialize,
37 throws ClassNotFoundException;
38 public native Class[] getClasses ();
39 public native ClassLoader getClassLoader ();
40 public native Class getComponentType ();
42 public native Constructor getConstructor (Class[] parameterTypes)
43 throws NoSuchMethodException, SecurityException;
45 // This is used to implement getConstructors and
46 // getDeclaredConstructors.
47 private native Constructor[] _getConstructors (boolean declared)
48 throws SecurityException;
50 public Constructor[] getConstructors () throws SecurityException
52 return _getConstructors (false);
55 public native Constructor getDeclaredConstructor (Class[] parameterTypes)
56 throws NoSuchMethodException, SecurityException;
58 public native Class[] getDeclaredClasses () throws SecurityException;
60 public Constructor[] getDeclaredConstructors () throws SecurityException
62 return _getConstructors (true);
65 public native Field getDeclaredField (String fieldName)
66 throws NoSuchFieldException, SecurityException;
67 public native Field[] getDeclaredFields () throws SecurityException;
69 private native Method _getDeclaredMethod (String methodName,
70 Class[] parameterTypes);
72 public Method getDeclaredMethod (String methodName, Class[] parameterTypes)
73 throws NoSuchMethodException, SecurityException
75 SecurityManager sm = System.getSecurityManager();
78 sm.checkMemberAccess(this, Member.DECLARED);
79 Package p = getPackage();
81 sm.checkPackageAccess(p.getName());
84 if ("<init>".equals(methodName) || "<clinit>".equals(methodName))
85 throw new NoSuchMethodException(methodName);
87 Method m = _getDeclaredMethod(methodName, parameterTypes);
89 throw new NoSuchMethodException (methodName);
93 public native Method[] getDeclaredMethods () throws SecurityException;
95 // This is marked as unimplemented in the JCL book.
96 public native Class getDeclaringClass ();
98 private native Field getField (String fieldName, int hash)
99 throws NoSuchFieldException, SecurityException;
101 public Field getField (String fieldName)
102 throws NoSuchFieldException, SecurityException
104 SecurityManager s = System.getSecurityManager();
106 s.checkMemberAccess (this, java.lang.reflect.Member.DECLARED);
107 Field fld = getField(fieldName, fieldName.hashCode());
109 throw new NoSuchFieldException(fieldName);
113 private native Field[] _getFields (Field[] result, int offset);
114 public native Field[] getFields () throws SecurityException;
117 * Returns the <code>Package</code> in which this class is defined
118 * Returns null when this information is not available from the
119 * classloader of this class or when the classloader of this class
124 public Package getPackage()
126 ClassLoader cl = getClassLoader();
129 String name = getName();
131 int idx = name.lastIndexOf('.');
133 pkg = name.substring(0, idx);
134 return cl.getPackage(pkg);
140 public native Class[] getInterfaces ();
142 private final native void getSignature (StringBuffer buffer);
143 private static final native String getSignature (Class[] parameterTypes,
144 boolean is_construtor);
146 public native Method _getMethod (String methodName, Class[] parameterTypes);
148 public Method getMethod (String methodName, Class[] parameterTypes)
149 throws NoSuchMethodException, SecurityException
151 SecurityManager sm = System.getSecurityManager();
154 sm.checkMemberAccess(this, Member.PUBLIC);
155 Package p = getPackage();
157 sm.checkPackageAccess(p.getName());
160 if ("<init>".equals(methodName) || "<clinit>".equals(methodName))
161 throw new NoSuchMethodException(methodName);
163 Method m = _getMethod(methodName, parameterTypes);
165 throw new NoSuchMethodException (methodName);
169 private native int _getMethods (Method[] result, int offset);
170 public native Method[] getMethods () throws SecurityException;
172 public native int getModifiers ();
173 public native String getName ();
175 public java.net.URL getResource (String resourceName)
177 String name = resourcePath (resourceName);
178 ClassLoader loader = getClassLoader ();
180 return ClassLoader.getSystemResource (name);
182 return loader.getResource (name);
185 public java.io.InputStream getResourceAsStream (String resourceName)
187 String name = resourcePath (resourceName);
188 ClassLoader loader = getClassLoader ();
190 return ClassLoader.getSystemResourceAsStream (name);
192 return loader.getResourceAsStream (name);
195 private String resourcePath (String resourceName)
197 if (resourceName.startsWith ("/"))
198 return resourceName.substring (1);
202 c = c.getComponentType ();
204 String packageName = c.getName ().replace ('.', '/');
205 int end = packageName.lastIndexOf ('/');
209 return packageName.substring (0, end+1) + resourceName;
212 // FIXME: implement. Requires java.security.
213 public Object[] getSigners ()
218 public native Class getSuperclass ();
219 public native boolean isArray ();
220 public native boolean isAssignableFrom (Class cls);
221 public native boolean isInstance (Object obj);
222 public native boolean isInterface ();
223 public native boolean isPrimitive ();
224 public native Object newInstance ()
225 throws InstantiationException, IllegalAccessException;
227 // We need a native method to retrieve the protection domain, because we
228 // can't add fields to java.lang.Class that are accessible from Java.
229 private native ProtectionDomain getProtectionDomain0();
232 * Returns the protection domain of this class. If the classloader
233 * did not record the protection domain when creating this class
234 * the unknown protection domain is returned which has a <code>null</code>
235 * code source and all permissions.
237 * @exception SecurityException if a security manager exists and the caller
238 * does not have <code>RuntimePermission("getProtectionDomain")</code>.
242 public ProtectionDomain getProtectionDomain()
244 SecurityManager sm = System.getSecurityManager();
246 sm.checkPermission(ClassLoader.protectionDomainPermission);
248 ProtectionDomain protectionDomain = getProtectionDomain0();
250 if (protectionDomain == null)
251 return ClassLoader.unknownProtectionDomain;
253 return protectionDomain;
256 public String toString ()
260 return (isInterface () ? "interface " : "class ") + getName ();
264 * Returns the desired assertion status of this class, if it were to be
265 * initialized at this moment. The class assertion status, if set, is
266 * returned; the backup is the default package status; then if there is
267 * a class loader, that default is returned; and finally the system default
268 * is returned. This method seldom needs calling in user code, but exists
269 * for compilers to implement the assert statement. Note that there is no
270 * guarantee that the result of this method matches the class's actual
273 * @return the desired assertion status
274 * @see ClassLoader#setClassAssertionStatus(String, boolean)
275 * @see ClassLoader#setPackageAssertionStatus(String, boolean)
276 * @see ClassLoader#setDefaultAssertionStatus(boolean)
279 public boolean desiredAssertionStatus()
281 ClassLoader c = getClassLoader();
284 return VMClassLoader.defaultAssertionStatus();
285 if (c.classAssertionStatus != null)
288 status = c.classAssertionStatus.get(getName());
290 return status.equals(Boolean.TRUE);
294 status = ClassLoader.systemClassAssertionStatus.get(getName());
296 return status.equals(Boolean.TRUE);
298 if (c.packageAssertionStatus != null)
301 String name = getPackagePortion(getName());
303 status = c.packageAssertionStatus.get(null);
307 status = c.packageAssertionStatus.get(name);
308 name = getPackagePortion(name);
310 while (! "".equals(name) && status == null);
312 return status.equals(Boolean.TRUE);
316 String name = getPackagePortion(getName());
318 status = ClassLoader.systemPackageAssertionStatus.get(null);
322 status = ClassLoader.systemPackageAssertionStatus.get(name);
323 name = getPackagePortion(name);
325 while (! "".equals(name) && status == null);
327 return status.equals(Boolean.TRUE);
329 return c.defaultAssertionStatus;
332 // Don't allow new classes to be made.
337 // Do a security check.
338 private void checkMemberAccess (int flags)
340 SecurityManager sm = System.getSecurityManager();
342 sm.checkMemberAccess(this, flags);
345 // Initialize the class.
346 private native void initializeClass ();
349 protected native void finalize () throws Throwable;
352 * Strip the last portion of the name (after the last dot).
354 * @param name the name to get package of
355 * @return the package name, or "" if no package
357 private static String getPackagePortion(String name)
359 int lastInd = name.lastIndexOf('.');
362 return name.substring(0, lastInd);