1 |
/* |
/* java.lang.reflect.Constructor - reflection of Java constructors |
2 |
* java.lang.reflect.Constructor: part of the Java Class Libraries project. |
Copyright (C) 1998, 2001 Free Software Foundation, Inc. |
3 |
* Copyright (C) 1998, 2001 Free Software Foundation |
|
4 |
* |
This file is part of GNU Classpath. |
5 |
* This library is free software; you can redistribute it and/or |
|
6 |
* modify it under the terms of the GNU Library General Public |
GNU Classpath is free software; you can redistribute it and/or modify |
7 |
* License as published by the Free Software Foundation; either |
it under the terms of the GNU General Public License as published by |
8 |
* version 2 of the License, or (at your option) any later version. |
the Free Software Foundation; either version 2, or (at your option) |
9 |
* |
any later version. |
10 |
* This library is distributed in the hope that it will be useful, |
|
11 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
GNU Classpath is distributed in the hope that it will be useful, but |
12 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
WITHOUT ANY WARRANTY; without even the implied warranty of |
13 |
* Library General Public License for more details. |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 |
* |
General Public License for more details. |
15 |
* You should have received a copy of the GNU Library General Public |
|
16 |
* License along with this library; if not, write to the |
You should have received a copy of the GNU General Public License |
17 |
* Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
along with GNU Classpath; see the file COPYING. If not, write to the |
18 |
* Boston, MA 02111-1307, USA. |
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
19 |
*/ |
02111-1307 USA. |
20 |
|
|
21 |
|
As a special exception, if you link this library with other files to |
22 |
|
produce an executable, this library does not by itself cause the |
23 |
|
resulting executable to be covered by the GNU General Public License. |
24 |
|
This exception does not however invalidate any other reasons why the |
25 |
|
executable file might be covered by the GNU General Public License. */ |
26 |
|
|
27 |
|
|
28 |
package java.lang.reflect; |
package java.lang.reflect; |
29 |
|
|
30 |
/** |
/** |
31 |
** Constructor represents a constructor of a class. |
* The Constructor class represents a constructor of a class. It also allows |
32 |
** It will allow you to create a new instance of the class or get generic |
* dynamic creation of an object, via reflection. Invocation on Constructor |
33 |
** information about the constructor.<P> |
* objects knows how to do widening conversions, but throws |
34 |
** |
* {@link IllegalArgumentException} if a narrowing conversion would be |
35 |
** <B>Note:</B> This class returns and accepts types as Classes, even |
* necessary. You can query for information on this Constructor regardless |
36 |
** primitive types; there are Class types defined that represent each |
* of location, but construction access may be limited by Java language |
37 |
** different primitive type. They are <code>java.lang.Boolean.TYPE, |
* access controls. If you can't do it in the compiler, you can't normally |
38 |
** java.lang.Byte.TYPE, </code>etc. These are not to be confused with |
* do it here either.<p> |
39 |
** the classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., |
* |
40 |
** which are real classes.<P> |
* <B>Note:</B> This class returns and accepts types as Classes, even |
41 |
** |
* primitive types; there are Class types defined that represent each |
42 |
** <STRONG>Serialization:</STRONG>Note that this is not a serializable |
* different primitive type. They are <code>java.lang.Boolean.TYPE, |
43 |
** class. It is entirely feasible to make it serializable, but this |
* java.lang.Byte.TYPE,</code>, also available as <code>boolean.class, |
44 |
** is on Sun, not me.<P> |
* byte.class</code>, etc. These are not to be confused with the |
45 |
** |
* classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are |
46 |
** <STRONG>Access and Security:</STRONG> Once this Constructor is created |
* real classes.<p> |
47 |
** by java.lang.Class (which does its own security check), any object may |
* |
48 |
** query it for information like parameter types, exception types, etc. |
* Also note that this is not a serializable class. It is entirely feasible |
49 |
** However, the Constructor may only be invoked using standard Java |
* to make it serializable using the Externalizable interface, but this is |
50 |
** language access controls. The JLS says that reflective access to all |
* on Sun, not me. |
51 |
** private, public and protected reflective members is granted to any |
* |
52 |
** class which can be linked against the reflected member. Link-level |
* @author John Keiser |
53 |
** enforcement is the enforcement of public, private, protected and |
* @author Eric Blake <ebb9@email.byu.edu> |
54 |
** default access rules, based on the caller's relationship to the class |
* @see Member |
55 |
** (same package, subclass, or unrelated). Thus, if you couldn't |
* @see Class |
56 |
** normally invoke this constructor from the calling class, you can't do |
* @see java.lang.Class#getConstructor(Object[]) |
57 |
** it using a Constructor object either.<P> |
* @see java.lang.Class#getDeclaredConstructor(Object[]) |
58 |
** |
* @see java.lang.Class#getConstructors() |
59 |
** The relevant section of the VM spec on link-security is <A |
* @see java.lang.Class#getDeclaredConstructors() |
60 |
** HREF='http://java.sun.com/docs/books/vmspec/html/Concepts.doc.html#22574'>2.16.3</A>, under Resolution. |
* @since 1.1 |
61 |
** A summary of the appropriate rules follows.<P> |
* @status updated to 1.4 |
62 |
** |
*/ |
63 |
** <STRONG>Summary of access rules</STRONG><BR> |
public final class Constructor |
64 |
** Two checks are done, and they are the same checks--on both the member's class and the member itself: |
extends AccessibleObject implements Member |
65 |
** <UL> |
{ |
66 |
** <LI>If the caller is the same class as the member's class, then it can access the member no matter |
private Class clazz; |
67 |
** what.</LI> |
private int slot; |
68 |
** <LI>If the caller is in the same package as the member's class, then the member's class and the member |
private Class[] parameterTypes; |
69 |
** itself must both be public, protected or default access.</LI> |
private Class[] exceptionTypes; |
70 |
** <LI>If the caller is a subclass of the member's class, then the member's class and the member itself must |
|
71 |
** both be public or protected access.</LI> |
/** |
72 |
** <LI>If the caller is unrelated member's class, then the member's class and the member must |
* This class is uninstantiable except from native code. |
73 |
** be public access.</LI> |
*/ |
74 |
** </UL> |
private Constructor(Class declaringClass,int slot) |
75 |
** <P> |
{ |
76 |
** |
this.clazz = declaringClass; |
77 |
** As far as I can tell from the fairly confusing <A |
this.slot = slot; |
78 |
** HREF='http://java.sun.com/products/jdk/1.1/docs/guide/innerclasses/spec/innerclasses.doc.html'>Inner |
} |
79 |
** Classes Specification</A>, there should be no change to these rules from the addition of inner |
|
80 |
** classes in 1.1.<P> |
private Constructor() |
81 |
** |
{ |
82 |
** <STRONG>Version note:</STRONG> In 1.2, the security checks can be disabled in the AccessibleObject |
} |
83 |
** interface. But this ain't 1.2. :)<P> |
|
84 |
** |
/** |
85 |
** <STRONG>BUGS:</STRONG> The maximum size of a signature right now is 4096 characters because I'm using |
* Gets the class that declared this constructor. |
86 |
** a static buffer when I calculate them. While fine for most purposes, it is for pathological cases that |
* @return the class that declared this member |
87 |
** specs are built. I'm not sure how I'll handle this yet. |
*/ |
88 |
** |
public Class getDeclaringClass() |
89 |
** @author John Keiser |
{ |
90 |
** @version 1.1.0, 31 May 1998 |
return clazz; |
91 |
** @see Member |
} |
92 |
** @see java.lang.Class#getConstructor(Object[]) |
|
93 |
** @see java.lang.Class#getDeclaredConstructor(Object[]) |
/** |
94 |
** @see java.lang.Class#getConstructors() |
* Gets the name of this constructor (the non-qualified name of the class |
95 |
** @see java.lang.Class#getDeclaredConstructors() |
* it was declared in). |
96 |
**/ |
* @return the name of this constructor |
97 |
|
*/ |
98 |
public final class Constructor implements Member { |
public String getName() |
99 |
private Class clazz; |
{ |
100 |
private int slot; |
return getDeclaringClass().getName(); |
101 |
private Class[] parameterTypes; |
} |
102 |
private Class[] exceptionTypes; |
|
103 |
|
/** |
104 |
/* This class is uninstantiable except from native code. */ |
* Gets the modifiers this constructor uses. Use the <code>Modifier</code> |
105 |
private Constructor(Class declaringClass,int slot) { |
* class to interpret the values. A constructor can only have a subset of the |
106 |
this.clazz = declaringClass; |
* following modifiers: public, private, protected. |
107 |
this.slot = slot; |
* |
108 |
} |
* @return an integer representing the modifiers to this Member |
109 |
|
* @see Modifier |
110 |
private Constructor() { |
*/ |
111 |
} |
public native int getModifiers(); |
112 |
|
|
113 |
/** Gets the class that declared this constructor. |
/** |
114 |
** @specnote It is unclear whether this returns the class that |
* Get the parameter list for this constructor, in declaration order. If the |
115 |
** actually syntactically declared the member, or the |
* constructor takes no parameters, returns a 0-length array (not null). |
116 |
** class where the Constructor object was gotten from. |
* |
117 |
** @return the class that declared this member. |
* @return a list of the types of the constructor's parameters |
118 |
**/ |
*/ |
119 |
public Class getDeclaringClass() { |
public Class[] getParameterTypes() |
120 |
return clazz; |
{ |
121 |
} |
if (parameterTypes == null) |
122 |
|
return new Class[0]; |
123 |
/** Gets the modifiers this constructor uses. Use the <code>Modifier</code> |
return parameterTypes; |
124 |
** class to interpret the values. |
} |
125 |
** A Constructor may only have the modifiers public, private and protected. |
|
126 |
** @see Modifier |
/** |
127 |
** @return an integer representing the modifiers to this Member. |
* Get the exception types this constructor says it throws, in no particular |
128 |
**/ |
* order. If the constructor has no throws clause, returns a 0-length array |
129 |
public native int getModifiers(); |
* (not null). |
130 |
|
* |
131 |
/** Gets the name of this constructor (the non-qualified name of the class it was declared in). |
* @return a list of the types in the constructor's throws clause |
132 |
** @return the name of this constructor. |
*/ |
133 |
**/ |
public Class[] getExceptionTypes() |
134 |
public String getName() { |
{ |
135 |
return getDeclaringClass().getName(); |
if (exceptionTypes == null) |
136 |
} |
return new Class[0]; |
137 |
|
return exceptionTypes; |
138 |
/** Get the parameter list for this constructor. |
} |
139 |
** @return a list of classes representing the names of the constructor's parameters. |
|
140 |
**/ |
/** |
141 |
public Class[] getParameterTypes() { |
* Compare two objects to see if they are semantically equivalent. |
142 |
if (parameterTypes == null) |
* Two Constructors are semantically equivalent if they have the same |
143 |
return(new Class[0]); |
* declaring class and the same parameter list. This ignores different |
144 |
return(parameterTypes); |
* exception clauses, but since you can't create a Method except through the |
145 |
} |
* VM, this is just the == relation. |
146 |
|
* |
147 |
/** Get the exception types this constructor says it throws. |
* @param o the object to compare to |
148 |
** @return a list of classes representing the exception types. |
* @return <code>true</code> if they are equal; <code>false</code> if not. |
149 |
**/ |
*/ |
150 |
public Class[] getExceptionTypes() { |
public boolean equals(Object o) |
151 |
if (exceptionTypes == null) |
{ |
152 |
return(new Class[0]); |
return this == o; |
153 |
return(exceptionTypes); |
} |
154 |
} |
|
155 |
|
/** |
156 |
/** Compare two objects to see if they are semantically equivalent. |
* Get the hash code for the Constructor. The Constructor hash code is the |
157 |
** Two Constructors are semantically equivalent if they have the same declaring class and the |
* hash code of the declaring class's name. |
158 |
** same parameter list. <B>Though I really don't see how two different Constructor objects with |
* |
159 |
** identical parameters could be created.</B> |
* @return the hash code for the object |
160 |
** @param o the object to compare to. |
*/ |
161 |
** @return <code>true</code> if they are equal; <code>false</code> if not. |
public int hashCode() |
162 |
**/ |
{ |
163 |
public boolean equals(Object o) { |
return getDeclaringClass().getName().hashCode(); |
164 |
return this == o; |
} |
165 |
} |
|
166 |
|
/** |
167 |
/** Get the hash code for the Constructor. |
* Get a String representation of the Constructor. A Constructor's String |
168 |
** Constructor hash code is the hash code of the declaring class's name. |
* representation is "<modifier> <classname>(<paramtypes>) |
169 |
** @return the hash code for the object. |
* throws <exceptions>", where everything after ')' is omitted if |
170 |
**/ |
* there are no exceptions.<br> Example: |
171 |
public int hashCode() { |
* <code>public java.io.FileInputStream(java.lang.Runnable) |
172 |
return getDeclaringClass().getName().hashCode(); |
* throws java.io.FileNotFoundException</code> |
173 |
} |
* |
174 |
|
* @return the String representation of the Constructor |
175 |
/** Get a String representation of the Constructor. |
*/ |
176 |
** A Constructor's String representation is <modifiers> <classname>(<paramtypes>). |
public String toString() |
177 |
** Example: <code>public java.lang.Thread(java.lang.Runnable,int)</code> |
{ |
178 |
** @return the String representation of the Constructor. |
StringBuffer sb = new StringBuffer(); |
179 |
**/ |
Modifier.toString(getModifiers(), sb).append(' '); |
180 |
public String toString() { |
sb.append(getDeclaringClass().getName()).append('('); |
181 |
StringBuffer sb = new StringBuffer(); |
Class[] c = getParameterTypes(); |
182 |
sb.append(Modifier.toString(getModifiers())); |
if (c.length > 0) |
183 |
sb.append(' '); |
{ |
184 |
sb.append(getDeclaringClass().getName()); |
sb.append(c[0].getName()); |
185 |
sb.append('('); |
for (int i = 1; i < c.length; i++) |
186 |
Class[] c = getParameterTypes(); |
sb.append(',').append(c[i].getName()); |
187 |
if(c.length > 0) { |
} |
188 |
sb.append(c[0].getName()); |
sb.append(')'); |
189 |
for(int i = 1; i < c.length; i++) { |
c = getExceptionTypes(); |
190 |
sb.append(','); |
if (e.length > 0) |
191 |
sb.append(c[i].getName()); |
{ |
192 |
} |
sb.append(" throws ").append(c[0].getName()); |
193 |
} |
for (int i = 1; i < c.length; i++) |
194 |
return sb.toString(); |
sb.append(',').append(c[i].getName()); |
195 |
} |
} |
196 |
|
return sb.toString(); |
197 |
|
} |
198 |
|
|
199 |
/** Create a new instance of the object the constructor can construct. |
/** |
200 |
** The constructor will permit widening argument conversions, but not narrowing conversions. |
* Create a new instance by invoking the constructor. Arguments are |
201 |
** @param args the arguments to the constructor. |
* automatically unwrapped and widened, if needed.<p> |
202 |
** @return the newly created object. |
* |
203 |
** @exception InstantiationException if the class is abstract. |
* If this class is abstract, you will get an |
204 |
** @exception IllegalAccessException if the constructor could not normally be called |
* <code>InstantiationException</code>. If the constructor takes 0 |
205 |
** by the Java code (i.e. it is not public). |
* arguments, you may use null or a 0-length array for <code>args</code>.<p> |
206 |
** @exception IllegalArgumentException if the number of arguments is incorrect, or if the |
* |
207 |
** arguments cannot be converted to the actual argument |
* If this Constructor enforces access control, your runtime context is |
208 |
** types, even with a widening conversion. |
* evaluated, and you may have an <code>IllegalAccessException</code> if |
209 |
** @exception InvocationTargetException if the constructor throws an exception. |
* you could not create this object in similar compiled code. If the class |
210 |
**/ |
* is uninitialized, you trigger class initialization, which may end in a |
211 |
public Object newInstance(Object args[]) |
* <code>ExceptionInInitializerError</code>.<p> |
212 |
throws InstantiationException, |
* |
213 |
IllegalAccessException, |
* Then, the constructor is invoked. If it completes normally, the return |
214 |
IllegalArgumentException, |
* value will be the new object. If it completes abruptly, the exception is |
215 |
InvocationTargetException { |
* wrapped in an <code>InvocationTargetException</code>. |
216 |
return constructNative(args, clazz, slot); |
* |
217 |
} |
* @param args the arguments to the constructor |
218 |
|
* @return the newly created object |
219 |
private native Object constructNative(Object[] args, Class declaringClass, int slot); |
* @throws IllegalAccessException if the constructor could not normally be |
220 |
|
* called by the Java code (i.e. it is not public) |
221 |
|
* @throws IllegalArgumentException if the number of arguments is incorrect; |
222 |
|
* or if the arguments types are wrong even with a widening |
223 |
|
* conversion |
224 |
|
* @throws InstantiationException if the class is abstract |
225 |
|
* @throws InvocationTargetException if the constructor throws an exception |
226 |
|
* @throws ExceptionInInitializerError if construction triggered class |
227 |
|
* initialization, which then failed |
228 |
|
*/ |
229 |
|
public Object newInstance(Object args[]) |
230 |
|
throws InstantiationException, IllegalAccessException, |
231 |
|
InvocationTargetException |
232 |
|
{ |
233 |
|
return constructNative(args, clazz, slot); |
234 |
|
} |
235 |
|
|
236 |
|
private native Object constructNative(Object[] args, Class declaringClass, |
237 |
|
int slot) |
238 |
|
throws InstantiationException, IllegalAccessException, |
239 |
|
InvocationTargetException; |
240 |
} |
} |