summaryrefslogtreecommitdiffstats
path: root/Master/Reference Architectures and Patterns/hjp5/html/k100275.html
blob: c588d11f1c101591259f20f118fb973c6d7aa67e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
<html>
<head>
<title>
Handbuch der Java-Programmierung, 5. Auflage
</title>
</head>
<body>
<a name="startofbody"></a>
<script language="JavaScript" src="hjp4lib.js">
</script>
<script language="JavaScript">
installKbdHandler("97,#startofbody;101,#endofbody;116,cover.html;122,k100003.html;115,search.html;105,index.html;100,JDKDOCS;112,APIDOCS;104,k100271.html;106,k100274.html;107,k100276.html;108,k100279.html");
</script>
<table border=0 cellpadding=0 cellspacing=1 width="100%">
<tr bgcolor="#EEFFCC">
<td width="7%" align=center bgcolor="#DDCC99"><a href="cover.html">&nbsp;Titel&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100003.html">&nbsp;Inhalt&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="search.html">&nbsp;Suchen&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="index.html">&nbsp;Index&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/index.html" onClick="this.href=getDocIndex()">&nbsp;DOC&nbsp;</a>
<td align="right">Handbuch der Java-Programmierung, 5. Auflage
<tr bgcolor="#EEFFCC">
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100271.html">&nbsp;&lt;&lt;&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100274.html">&nbsp;&nbsp;&lt;&nbsp;&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100276.html">&nbsp;&nbsp;&gt;&nbsp;&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100279.html">&nbsp;&gt;&gt;&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/api/index.html" onClick="this.href=getApiIndex()">&nbsp;API&nbsp;</a>
<td align="right">Kapitel 43 - Reflection
</table>
<hr>


<!-- Section -->
<a name="sectionrefmember"></a>
<h2>43.4 Zugriff auf Membervariablen </h2>
<hr>
<ul>
<li><a href="k100275.html#sectionrefmember">43.4 Zugriff auf Membervariablen</a>
</ul>
<hr>

<p>
Nachdem wir uns in den vorangegangenen Abschnitten die beiden Reflection-Aspekte
<i>Instanzierung</i> und <i>Methodenaufruf</i> angesehen haben, wollen
wir uns nun mit dem Zugriff auf Membervariablen (also auf die &#187;Felder&#171;
eines Objekts) mit Hilfe von Reflection besch&auml;ftigen. Prinzipiell
gibt es keine gro&szlig;en Unterschiede gegen&uuml;ber dem Zugriff
auf eine Methode oder einen Konstruktor: 
<ol type=1>
<li>Zun&auml;chst wird ein Klassenobjekt f&uuml;r das zu bearbeitende
Objekt beschafft.
<li>Dann wird eine Methode aufgerufen, um ein Bearbeitungsobjekt f&uuml;r
eine ganz bestimmte oder eine Liste aller Membervariablen zu beschaffen.
<li>Das Bearbeitungsobjekt wird verwendet, um die Membervariable zu
lesen, zu ver&auml;ndern oder andere Eigenschaften abzufragen.
</ol>

<p>
Der erste Schritt erfolgt wie gewohnt durch Aufruf von <a href="index_g.html#ixb100781"><font color=#000080><tt>getClass</tt></font></a>
oder die <font color="#000077"><tt>.class</tt></font>-Notation. Die
im zweiten Schritt ben&ouml;tigten Bearbeitungsobjekte sind vom Typ
<a name="ixa103220"><a href="index_f.html#ixb102373"><font color=#000080><tt>Field</tt></font></a></a>,
sie k&ouml;nnen auf dem Klassenobjekt durch Aufruf einer der folgenden
Methoden beschafft werden: 
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
<tr>
<td valign=top width=100%>
<font color="#660066">
<pre>
Field getField(String name)
Field[] getFields()

Field getDeclaredField(String name)
Field[] getDeclaredFields()
</pre>
</font>
</td>
<td valign=top>
<a href="../jdkdocs/api/java/lang/Class.html" onClick="this.href=getApiDoc('java.lang.Class')"><font color="#660066" size=-1>java.lang.Class</font></a></td>
</tr>
</table>

<p>
Mit <a name="ixa103221"><a href="index_g.html#ixb102374"><font color=#000080><tt>getField</tt></font></a></a>
wird die Membervariable mit dem angegebenen Namen beschafft, und <a name="ixa103222"><a href="index_g.html#ixb102375"><font color=#000080><tt>getFields</tt></font></a></a>
liefert ein Array mit <a href="index_f.html#ixb102373"><font color=#000080><tt>Field</tt></font></a>-Objekten
zu allen &ouml;ffentlichen Membervariablen. Die beiden Methoden <a name="ixa103223"><a href="index_g.html#ixb102376"><font color=#000080><tt>getDeclaredField</tt></font></a></a>
und <a name="ixa103224"><a href="index_g.html#ixb102377"><font color=#000080><tt>getDeclaredFields</tt></font></a></a>
liefern dar&uuml;ber hinaus auch nicht-&ouml;ffentliche Membervariablen.

<p>
Die Klasse <a href="index_f.html#ixb102373"><font color=#000080><tt>Field</tt></font></a>
besitzt Methoden zum Zugriff auf die Membervariable: 
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
<tr>
<td valign=top width=100%>
<font color="#660066">
<pre>
Class getType()

Object get(Object obj)

void set(Object obj, Object value)
</pre>
</font>
</td>
<td valign=top>
<a href="../jdkdocs/api/java/lang/reflect/Field.html" onClick="this.href=getApiDoc('java.lang.reflect.Field')"><font color="#660066" size=-1>java.lang.reflect.Field</font></a></td>
</tr>
</table>

<p>
Mit <a name="ixa103225"><a href="index_g.html#ixb102378"><font color=#000080><tt>getType</tt></font></a></a>
kann der Typ der Membervariable bestimmt werden. Das zur&uuml;ckgegebene
Klassenobjekt beschreibt ihn in derselben Weise wie beispielsweise
das Parameterobjekt von <a href="index_g.html#ixb102368"><font color=#000080><tt>getMethod</tt></font></a>.
Mit <a name="ixa103226"><a href="index_g.html#ixb100699"><font color=#000080><tt>get</tt></font></a></a>
kann auf den Wert zugegriffen werden, den die Membervariable in dem
als Argument &uuml;bergebenen Objekt hat. Handelt es sich um einen
primitiven Typ, wird dieser automatisch in die passende Wrapper-Klasse
verpackt und als Objekt zur&uuml;ckgegeben. Referenztypen werden unver&auml;ndert
zur&uuml;ckgegeben. Mit Hilfe der Methode <a name="ixa103227"><a href="index_s.html#ixb100181"><font color=#000080><tt>set</tt></font></a></a>
kann der Wert einer Membervariable ver&auml;ndert werden. Das erste
Argument repr&auml;sentiert das zu ver&auml;nderende Objekt und das
zweite den neuen Wert der Membervariable. Soll ein primitiver Typ
ver&auml;ndert werden, muss er vor der &Uuml;bergabe in die passende
Wrapper-Klasse verpackt werden. 
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100%>
<tr>
<td width=1 align=left valign=top bgcolor="#0099CC"><img src="trp1_1.gif"></td>
<td><img src="trp1_1.gif" width=1></td>
<td width=1 align=left valign=top bgcolor="#0099CC"><img src="trp1_1.gif"></td>
<td><img src="trp1_1.gif" width=2></td>
<td valign=top width=1000>

<p>
Neben den generischen <a href="index_g.html#ixb100699"><font color=#000080><tt>get</tt></font></a>-
und <a href="index_s.html#ixb100181"><font color=#000080><tt>set</tt></font></a>-Methoden
gibt es diese auch in typisierter Form. So dient beispielsweise <a name="ixa103228"><a href="index_g.html#ixb102253"><font color=#000080><tt>getInt</tt></font></a></a>
dazu, ein <a href="index_i.html#ixb100244"><font color=#000080><tt>int</tt></font></a>-Feld
abzufragen, mit <a name="ixa103229"><a href="index_g.html#ixb102258"><font color=#000080><tt>getDouble</tt></font></a></a>
kann auf ein <a href="index_d.html#ixb100247"><font color=#000080><tt>double</tt></font></a>
zugegriffen werden usw. Das Gegenst&uuml;ck dazu sind die Methoden
<a name="ixa103230"><a href="index_s.html#ixb102379"><font color=#000080><tt>setInt</tt></font></a></a>,
<a name="ixa103231"><a href="index_s.html#ixb102380"><font color=#000080><tt>setDouble</tt></font></a></a>
usw., mit denen die Membervariablen typisiert ver&auml;ndert werden
k&ouml;nnen.</td>
<td><img src="trp1_1.gif" width=2></td>
<td valign=top>
<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#0099CC">
<tr>
<td><font color="#FFFFFF">&nbsp;Tipp&nbsp;</font></td>
</tr>
</table>
</td>
<td width=1 align=left valign=top bgcolor="#0099CC"><img src="trp1_1.gif"></td>
</tr>
</table>

<p>
Wir wollen als Beispiel eine Klasse <font color="#000077"><tt>PrintableObject</tt></font>
erstellen, die direkt aus <a href="index_o.html#ixb100224"><font color=#000080><tt>Object</tt></font></a>
abgeleitet ist und die Methode <a href="index_t.html#ixb100327"><font color=#000080><tt>toString</tt></font></a>
&uuml;berlagert. Im Gegensatz zur Implementierung von <a href="index_o.html#ixb100224"><font color=#000080><tt>Object</tt></font></a>
soll unsere Variante von <a href="index_t.html#ixb100327"><font color=#000080><tt>toString</tt></font></a>
in der Lage sein, die Namen und Inhalte aller Membervariablen des
zugeh&ouml;rigen Objekts auszugeben: 
<a name="listingid043007"></a>

<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#DDDDDD">
<tr>
<td valign=top>
<font color="#000055">
<pre>
<font color="#555555">001 </font><font color="#00AA00">/* PrintableObject.java */</font>
<font color="#555555">002 </font>
<font color="#555555">003 </font><font color="#0000AA">import</font> java.lang.reflect.*;
<font color="#555555">004 </font>
<font color="#555555">005 </font><font color="#0000AA">public</font> <font color="#0000AA">class</font> PrintableObject
<font color="#555555">006 </font>{
<font color="#555555">007 </font>  <font color="#0000AA">public</font> String toString()
<font color="#555555">008 </font>  {
<font color="#555555">009 </font>    StringBuffer sb = <font color="#0000AA">new</font> StringBuffer(200);
<font color="#555555">010 </font>    Class clazz = getClass();
<font color="#555555">011 </font>    <font color="#0000AA">while</font> (clazz != <font color="#006699">null</font>) {
<font color="#555555">012 </font>      Field[] fields = clazz.getDeclaredFields();
<font color="#555555">013 </font>      <font color="#0000AA">for</font> (<font color="#006699">int</font> i = 0; i &lt; fields.length; ++i) {
<font color="#555555">014 </font>        sb.append(fields[i].getName() + <font color="#0000FF">" = "</font>);
<font color="#555555">015 </font>        <font color="#0000AA">try</font> {
<font color="#555555">016 </font>          Object obj = fields[i].get(<font color="#006699">this</font>);
<font color="#555555">017 </font>          <font color="#0000AA">if</font> (obj.getClass().isArray()) {
<font color="#555555">018 </font>            Object[] ar = (Object[])obj;
<font color="#555555">019 </font>            <font color="#0000AA">for</font> (<font color="#006699">int</font> j = 0; j &lt; ar.length; ++j) {
<font color="#555555">020 </font>              sb.append(ar[j].toString() + <font color="#0000FF">" "</font>);
<font color="#555555">021 </font>            }
<font color="#555555">022 </font>            sb.append(<font color="#0000FF">"\n"</font>);
<font color="#555555">023 </font>          } <font color="#0000AA">else</font> {
<font color="#555555">024 </font>            sb.append(obj.toString() + <font color="#0000FF">"\n"</font>);
<font color="#555555">025 </font>          }
<font color="#555555">026 </font>        } <font color="#0000AA">catch</font> (IllegalAccessException e) {
<font color="#555555">027 </font>          sb.append(e.toString() + <font color="#0000FF">"\n"</font>);
<font color="#555555">028 </font>        }
<font color="#555555">029 </font>      }
<font color="#555555">030 </font>      clazz = clazz.getSuperclass();
<font color="#555555">031 </font>    }
<font color="#555555">032 </font>    <font color="#0000AA">return</font> sb.toString();
<font color="#555555">033 </font>  }
<font color="#555555">034 </font>
<font color="#555555">035 </font>  <font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">void</font> main(String[] args)
<font color="#555555">036 </font>  {
<font color="#555555">037 </font>    JavaProgrammer jim = <font color="#0000AA">new</font> JavaProgrammer();
<font color="#555555">038 </font>    jim.name           = <font color="#0000FF">"Jim Miller"</font>;
<font color="#555555">039 </font>    jim.department     = <font color="#0000FF">"Operating Systems"</font>;
<font color="#555555">040 </font>    jim.age            = 32;
<font color="#555555">041 </font>    String[] langs     = {<font color="#0000FF">"C"</font>, <font color="#0000FF">"Pascal"</font>, <font color="#0000FF">"PERL"</font>, <font color="#0000FF">"Java"</font>};
<font color="#555555">042 </font>    jim.languages      = langs;
<font color="#555555">043 </font>    jim.linesofcode    = 55000;
<font color="#555555">044 </font>    jim.jdk12          = <font color="#006699">true</font>;
<font color="#555555">045 </font>    jim.swing          = <font color="#006699">false</font>;
<font color="#555555">046 </font>    System.out.println(jim);
<font color="#555555">047 </font>  }
<font color="#555555">048 </font>}
<font color="#555555">049 </font>
<font color="#555555">050 </font><font color="#0000AA">class</font> Employee
<font color="#555555">051 </font><font color="#0000AA">extends</font> PrintableObject
<font color="#555555">052 </font>{
<font color="#555555">053 </font>  <font color="#0000AA">public</font> String name;
<font color="#555555">054 </font>  <font color="#0000AA">public</font> String department;
<font color="#555555">055 </font>  <font color="#0000AA">public</font> <font color="#006699">int</font>    age;
<font color="#555555">056 </font>}
<font color="#555555">057 </font>
<font color="#555555">058 </font><font color="#0000AA">class</font> Programmer
<font color="#555555">059 </font><font color="#0000AA">extends</font> Employee
<font color="#555555">060 </font>{
<font color="#555555">061 </font>  <font color="#0000AA">public</font> String[] languages;
<font color="#555555">062 </font>  <font color="#0000AA">public</font> <font color="#006699">int</font>      linesofcode;
<font color="#555555">063 </font>}
<font color="#555555">064 </font>
<font color="#555555">065 </font><font color="#0000AA">class</font> JavaProgrammer
<font color="#555555">066 </font><font color="#0000AA">extends</font> Programmer
<font color="#555555">067 </font>{
<font color="#555555">068 </font>  <font color="#0000AA">public</font> <font color="#006699">boolean</font> jdk12;
<font color="#555555">069 </font>  <font color="#0000AA">public</font> <font color="#006699">boolean</font> swing;
<font color="#555555">070 </font>}</pre>
</font>
</td>
<td valign=top align=right>
<a href="../examples/PrintableObject.java"><font color="#000055" size=-1>PrintableObject.java</font></a></td>
</tr>
</table>
<i>
Listing 43.7: Die Klasse PrintableObject</i></p>

<p>
<a href="index_t.html#ixb100327"><font color=#000080><tt>toString</tt></font></a>
besorgt zun&auml;chst ein Klassenobjekt zum aktuellen Objekt. Mit
<a href="index_g.html#ixb102377"><font color=#000080><tt>getDeclaredFields</tt></font></a>
wird dann eine Liste <i>aller</i> Felder (nicht nur der &ouml;ffentlichen)
dieser Klasse besorgt und jeweils mit <a href="index_g.html#ixb100667"><font color=#000080><tt>getName</tt></font></a>
sein Name und mit <a href="index_g.html#ixb100699"><font color=#000080><tt>get</tt></font></a>
sein Wert ausgegeben. Wir machen uns dabei die F&auml;higkeit zunutze,
dass alle Objekte (auch die Wrapper-Klassen der primitiven Typen)
eine Methode <a href="index_t.html#ixb100327"><font color=#000080><tt>toString</tt></font></a>
haben, die ihren Wert als String liefert. Ist die Membervariable ein
Array, durchl&auml;uft das Programm zus&auml;tzlich seine Elemente
und gibt sie einzeln aus. 

<p>
Da eine Klasse Membervariablen aus ihren Vaterklassen erbt, ist es
notwendig, die Vererbungshierarchie von unten nach oben zu durchlaufen,
denn <a href="index_g.html#ixb102377"><font color=#000080><tt>getDeclaredFields</tt></font></a>
liefert nur die Membervariablen der aktuellen Klasse. Der Aufruf von
<a name="ixa103232"><a href="index_g.html#ixb102381"><font color=#000080><tt>getSuperClass</tt></font></a></a>
am Ende der Schleife liefert zur aktuellen Klasse die Vaterklasse.
Ist der R&uuml;ckgabewert <a href="index_n.html#ixb100235"><font color=#000080><tt>null</tt></font></a>,
so ist das Ende der Vererbungshierarchie erreicht (<font color="#000077"><tt>clazz</tt></font>
repr&auml;sentiert dann die Klasse <a href="index_o.html#ixb100224"><font color=#000080><tt>Object</tt></font></a>)
und die Schleife wird beendet. 

<p>
Die Klassen <font color="#000077"><tt>Employee</tt></font>, <font color="#000077"><tt>Programmer</tt></font>
und <font color="#000077"><tt>JavaProgrammer</tt></font> zeigen beispielhaft
die Anwendung von <font color="#000077"><tt>PrintableObject</tt></font>.
<font color="#000077"><tt>Employee</tt></font> ist aus <font color="#000077"><tt>PrintableObject</tt></font>
abgeleitet und erbt die modifizierte Methode <a href="index_t.html#ixb100327"><font color=#000080><tt>toString</tt></font></a>.
<font color="#000077"><tt>Programmer</tt></font> ist aus <font color="#000077"><tt>Employee</tt></font>
abgeleitet und <font color="#000077"><tt>JavaProgrammer</tt></font>
aus <font color="#000077"><tt>Programmer</tt></font>. Das Hauptprogramm
erzeugt ein Objekt des Typs <font color="#000077"><tt>JavaProgrammer</tt></font>
und weist seinen eigenen und den geerbten Membervariablen Werte zu,
die durch den anschlie&szlig;enden Aufruf von <a href="index_t.html#ixb100327"><font color=#000080><tt>toString</tt></font></a>
auf dem Bildschirm ausgegeben werden. Die Ausgabe des Programms ist:
<font color="#333300">
<pre>
jdk12 = true
swing = false
languages = C Pascal PERL Java
linesofcode = 55000
name = Jim Miller
department = Operating Systems
age = 32
</pre>
</font>
<hr>
<table border=0 cellpadding=0 cellspacing=1 width="100%">
<tr bgcolor="#EEFFCC">
<td width="7%" align=center bgcolor="#DDCC99"><a href="cover.html">&nbsp;Titel&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100003.html">&nbsp;Inhalt&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="search.html">&nbsp;Suchen&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="index.html">&nbsp;Index&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/index.html" onClick="this.href=getDocIndex()">&nbsp;DOC&nbsp;</a>
<td align="right">Handbuch der Java-Programmierung, 5. Auflage, Addison
Wesley, Version 5.0.1
<tr bgcolor="#EEFFCC">
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100271.html">&nbsp;&lt;&lt;&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100274.html">&nbsp;&nbsp;&lt;&nbsp;&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100276.html">&nbsp;&nbsp;&gt;&nbsp;&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100279.html">&nbsp;&gt;&gt;&nbsp;</a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/api/index.html" onClick="this.href=getApiIndex()">&nbsp;API&nbsp;</a>
<td align="right">&copy; 1998, 2007 Guido Kr&uuml;ger &amp; Thomas
Stark, <a href="http://www.javabuch.de">http://www.javabuch.de</a>
</table>
<a name="endofbody"></a>
</body>
</html>