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
.*;
16 import java
.util
.Arrays
;
17 import java
.util
.HashSet
;
20 * @author Tom Tromey <tromey@cygnus.com>
21 * @date October 1, 1998
24 /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
25 * "The Java Language Specification", ISBN 0-201-63451-1
26 * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
27 * plus gcj compiler sources (to determine object layout)
28 * Status: Sufficient for our purposes, but some methods missing
29 * and some not implemented.
32 public final class Class
implements Serializable
34 public static native Class
forName (String className
)
35 throws ClassNotFoundException
;
37 public static native Class
forName (String className
, boolean initialize
,
39 throws ClassNotFoundException
;
40 public native Class
[] getClasses ();
41 public native ClassLoader
getClassLoader ();
42 public native Class
getComponentType ();
44 public native Constructor
getConstructor (Class
[] parameterTypes
)
45 throws NoSuchMethodException
, SecurityException
;
47 // This is used to implement getConstructors and
48 // getDeclaredConstructors.
49 private native Constructor
[] _getConstructors (boolean declared
)
50 throws SecurityException
;
52 public Constructor
[] getConstructors () throws SecurityException
54 return _getConstructors (false);
57 public native Constructor
getDeclaredConstructor (Class
[] parameterTypes
)
58 throws NoSuchMethodException
, SecurityException
;
60 public native Class
[] getDeclaredClasses () throws SecurityException
;
62 public Constructor
[] getDeclaredConstructors () throws SecurityException
64 return _getConstructors (true);
67 public native Field
getDeclaredField (String fieldName
)
68 throws NoSuchFieldException
, SecurityException
;
71 * Get all the declared fields in this class, but not those inherited from
72 * superclasses. This returns an array of length 0 if there are no fields,
73 * including for primitive types. This does not return the implicit length
74 * field of arrays. A security check may be performed, with
75 * <code>checkMemberAccess(this, Member.DECLARED)</code> as well as
76 * <code>checkPackageAccess</code> both having to succeed.
78 * @return all declared fields in this class
79 * @throws SecurityException if the security check fails
82 public Field
[] getDeclaredFields()
84 memberAccessCheck(Member
.DECLARED
);
85 return getDeclaredFields(false);
88 native Field
[] getDeclaredFields (boolean publicOnly
);
90 private native Method
_getDeclaredMethod (String methodName
,
91 Class
[] parameterTypes
);
93 public Method
getDeclaredMethod (String methodName
, Class
[] parameterTypes
)
94 throws NoSuchMethodException
, SecurityException
96 memberAccessCheck(Member
.DECLARED
);
98 if ("<init>".equals(methodName
) || "<clinit>".equals(methodName
))
99 throw new NoSuchMethodException(methodName
);
101 Method m
= _getDeclaredMethod(methodName
, parameterTypes
);
103 throw new NoSuchMethodException (methodName
);
107 public native Method
[] getDeclaredMethods () throws SecurityException
;
109 // This is marked as unimplemented in the JCL book.
110 public native Class
getDeclaringClass ();
112 private native Field
getField (String fieldName
, int hash
)
113 throws NoSuchFieldException
, SecurityException
;
115 public Field
getField (String fieldName
)
116 throws NoSuchFieldException
, SecurityException
118 memberAccessCheck (Member
.PUBLIC
);
119 Field fld
= getField(fieldName
, fieldName
.hashCode());
121 throw new NoSuchFieldException(fieldName
);
126 * Get all the public fields declared in this class or inherited from
127 * superclasses. This returns an array of length 0 if there are no fields,
128 * including for primitive types. This does not return the implicit length
129 * field of arrays. A security check may be performed, with
130 * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as
131 * <code>checkPackageAccess</code> both having to succeed.
133 * @return all public fields in this class
134 * @throws SecurityException if the security check fails
137 public Field
[] getFields()
139 memberAccessCheck(Member
.PUBLIC
);
140 return internalGetFields();
144 * Like <code>getFields()</code> but without the security checks.
146 private Field
[] internalGetFields()
148 HashSet set
= new HashSet();
149 set
.addAll(Arrays
.asList(getDeclaredFields(true)));
150 Class
[] interfaces
= getInterfaces();
151 for (int i
= 0; i
< interfaces
.length
; i
++)
152 set
.addAll(Arrays
.asList(interfaces
[i
].internalGetFields()));
153 Class superClass
= getSuperclass();
154 if (superClass
!= null)
155 set
.addAll(Arrays
.asList(superClass
.internalGetFields()));
156 return (Field
[])set
.toArray(new Field
[set
.size()]);
160 * Returns the <code>Package</code> in which this class is defined
161 * Returns null when this information is not available from the
162 * classloader of this class or when the classloader of this class
167 public Package
getPackage()
169 ClassLoader cl
= getClassLoader();
172 String name
= getName();
174 int idx
= name
.lastIndexOf('.');
176 pkg
= name
.substring(0, idx
);
177 return cl
.getPackage(pkg
);
183 public native Class
[] getInterfaces ();
185 private final native void getSignature (StringBuffer buffer
);
186 private static final native String
getSignature (Class
[] parameterTypes
,
187 boolean is_construtor
);
189 public native Method
_getMethod (String methodName
, Class
[] parameterTypes
);
191 public Method
getMethod (String methodName
, Class
[] parameterTypes
)
192 throws NoSuchMethodException
, SecurityException
194 memberAccessCheck(Member
.PUBLIC
);
196 if ("<init>".equals(methodName
) || "<clinit>".equals(methodName
))
197 throw new NoSuchMethodException(methodName
);
199 Method m
= _getMethod(methodName
, parameterTypes
);
201 throw new NoSuchMethodException (methodName
);
205 private native int _getMethods (Method
[] result
, int offset
);
206 public native Method
[] getMethods () throws SecurityException
;
208 public native int getModifiers ();
209 public native String
getName ();
211 public java
.net
.URL
getResource (String resourceName
)
213 String name
= resourcePath (resourceName
);
214 ClassLoader loader
= getClassLoader ();
216 return ClassLoader
.getSystemResource (name
);
218 return loader
.getResource (name
);
221 public java
.io
.InputStream
getResourceAsStream (String resourceName
)
223 String name
= resourcePath (resourceName
);
224 ClassLoader loader
= getClassLoader ();
226 return ClassLoader
.getSystemResourceAsStream (name
);
228 return loader
.getResourceAsStream (name
);
231 private String
resourcePath (String resourceName
)
233 if (resourceName
.startsWith ("/"))
234 return resourceName
.substring (1);
238 c
= c
.getComponentType ();
240 String packageName
= c
.getName ().replace ('.', '/');
241 int end
= packageName
.lastIndexOf ('/');
245 return packageName
.substring (0, end
+1) + resourceName
;
248 public native Object
[] getSigners ();
249 native void setSigners(Object
[] signers
);
251 public native Class
getSuperclass ();
252 public native boolean isArray ();
253 public native boolean isAssignableFrom (Class cls
);
254 public native boolean isInstance (Object obj
);
255 public native boolean isInterface ();
256 public native boolean isPrimitive ();
257 public native Object
newInstance ()
258 throws InstantiationException
, IllegalAccessException
;
260 // We need a native method to retrieve the protection domain, because we
261 // can't add fields to java.lang.Class that are accessible from Java.
262 private native ProtectionDomain
getProtectionDomain0();
265 * Returns the protection domain of this class. If the classloader
266 * did not record the protection domain when creating this class
267 * the unknown protection domain is returned which has a <code>null</code>
268 * code source and all permissions.
270 * @exception SecurityException if a security manager exists and the caller
271 * does not have <code>RuntimePermission("getProtectionDomain")</code>.
275 public ProtectionDomain
getProtectionDomain()
277 SecurityManager sm
= System
.getSecurityManager();
279 sm
.checkPermission(VMClassLoader
.protectionDomainPermission
);
281 ProtectionDomain protectionDomain
= getProtectionDomain0();
283 if (protectionDomain
== null)
284 return VMClassLoader
.unknownProtectionDomain
;
286 return protectionDomain
;
289 public String
toString ()
293 return (isInterface () ?
"interface " : "class ") + getName ();
297 * Returns the desired assertion status of this class, if it were to be
298 * initialized at this moment. The class assertion status, if set, is
299 * returned; the backup is the default package status; then if there is
300 * a class loader, that default is returned; and finally the system default
301 * is returned. This method seldom needs calling in user code, but exists
302 * for compilers to implement the assert statement. Note that there is no
303 * guarantee that the result of this method matches the class's actual
306 * @return the desired assertion status
307 * @see ClassLoader#setClassAssertionStatus(String, boolean)
308 * @see ClassLoader#setPackageAssertionStatus(String, boolean)
309 * @see ClassLoader#setDefaultAssertionStatus(boolean)
312 public boolean desiredAssertionStatus()
314 ClassLoader c
= getClassLoader();
317 return VMClassLoader
.defaultAssertionStatus();
318 if (c
.classAssertionStatus
!= null)
321 status
= c
.classAssertionStatus
.get(getName());
323 return status
.equals(Boolean
.TRUE
);
327 status
= ClassLoader
.systemClassAssertionStatus
.get(getName());
329 return status
.equals(Boolean
.TRUE
);
331 if (c
.packageAssertionStatus
!= null)
334 String name
= getPackagePortion(getName());
336 status
= c
.packageAssertionStatus
.get(null);
340 status
= c
.packageAssertionStatus
.get(name
);
341 name
= getPackagePortion(name
);
343 while (! "".equals(name
) && status
== null);
345 return status
.equals(Boolean
.TRUE
);
349 String name
= getPackagePortion(getName());
351 status
= ClassLoader
.systemPackageAssertionStatus
.get(null);
355 status
= ClassLoader
.systemPackageAssertionStatus
.get(name
);
356 name
= getPackagePortion(name
);
358 while (! "".equals(name
) && status
== null);
360 return status
.equals(Boolean
.TRUE
);
362 return c
.defaultAssertionStatus
;
365 // Don't allow new classes to be made.
370 // Initialize the class.
371 private native void initializeClass ();
374 protected native void finalize () throws Throwable
;
377 * Strip the last portion of the name (after the last dot).
379 * @param name the name to get package of
380 * @return the package name, or "" if no package
382 private static String
getPackagePortion(String name
)
384 int lastInd
= name
.lastIndexOf('.');
387 return name
.substring(0, lastInd
);
391 * Perform security checks common to all of the methods that
392 * get members of this Class.
394 private void memberAccessCheck(int which
)
396 SecurityManager sm
= System
.getSecurityManager();
399 sm
.checkMemberAccess(this, which
);
400 Package pkg
= getPackage();
402 sm
.checkPackageAccess(pkg
.getName());