1 00:00:00,740 --> 00:00:04,000 Reflection is a feature in programming languages where by you can 2 00:00:04,000 --> 00:00:07,810 write code to examine the structure of classes or objects, and 3 00:00:07,810 --> 00:00:10,490 even modify their structure and behavior. 4 00:00:10,490 --> 00:00:13,980 Right now we're not interested in modifying structure or behavior. 5 00:00:13,980 --> 00:00:17,430 We'll focus instead on examining the structure. 6 00:00:17,430 --> 00:00:22,210 That is, we'll want to write code that cracks the hood of the MathUtils object 7 00:00:22,210 --> 00:00:25,000 to look at its annotations and method declarations. 8 00:00:26,060 --> 00:00:29,870 Some refer to this part of reflection as introspection. 9 00:00:29,870 --> 00:00:32,610 For simplicity, I'll just use the term reflection. 10 00:00:34,140 --> 00:00:36,690 Let's hop over to the main class and practice some reflection 11 00:00:36,690 --> 00:00:39,900 techniques that will be helpful in processing our annotations. 12 00:00:39,900 --> 00:00:44,780 The first thing we'll need to be able to do is utilize the class object itself. 13 00:00:44,780 --> 00:00:48,693 Let's examine the structure of the MathUtils class by grabbing a reference to 14 00:00:48,693 --> 00:00:49,293 the class. 15 00:00:52,451 --> 00:00:55,395 Let's add a comment here saying that we're getting a class objects. 16 00:00:57,410 --> 00:00:58,910 And I will define it. 17 00:01:03,726 --> 00:01:06,070 And store into it a reference to the class. 18 00:01:07,570 --> 00:01:10,250 Now, hey, since we're using the MathUtils class for 19 00:01:10,250 --> 00:01:13,409 the first time in this Java file, let's be sure to import that. 20 00:01:18,701 --> 00:01:19,390 Wonderful. 21 00:01:20,790 --> 00:01:24,040 Notice that I'm not calling this variable class. 22 00:01:25,620 --> 00:01:29,150 Remember that class is a reserved keyword in Java, and 23 00:01:29,150 --> 00:01:31,780 in many other programming languages, as well. 24 00:01:31,780 --> 00:01:36,380 This means that it can't be used as an identifier to name a variable, a method, 25 00:01:36,380 --> 00:01:37,277 or a class. 26 00:01:37,277 --> 00:01:42,100 So one of convention is to replace the S's in class with Z's, 27 00:01:42,100 --> 00:01:42,990 which is what I've done here. 28 00:01:44,640 --> 00:01:47,710 Now that we have a reference to the class object itself, 29 00:01:47,710 --> 00:01:50,360 let's look at the MathUtils class's methods. 30 00:01:51,450 --> 00:01:54,930 You might think to yourself, what do you mean look at the class's methods? 31 00:01:54,930 --> 00:01:58,720 I could just click over to MathUtils.java and look at them myself. 32 00:01:58,720 --> 00:02:02,730 And you'd be right, but even though we programmers can 33 00:02:02,730 --> 00:02:06,680 look at a bunch of code and see everything that is present, the power of programming 34 00:02:06,680 --> 00:02:10,290 comes from having a computer do the work so that we don't have to. 35 00:02:10,290 --> 00:02:12,980 What we like to do is write some code that allows our application to get 36 00:02:12,980 --> 00:02:17,750 the details of an object during run time, this is reflection. 37 00:02:17,750 --> 00:02:22,230 After all the JVM will be able to do this much faster than we ever could. 38 00:02:22,230 --> 00:02:26,270 Also, we wouldn't have to plop ourselves in front of the computer while our program 39 00:02:26,270 --> 00:02:30,750 is examining these objects, but if we really insisted on sticking around 40 00:02:30,750 --> 00:02:33,505 while it runs we can at least grab a tasty beverage and 41 00:02:33,505 --> 00:02:35,100 kickback while our program does all the work. 42 00:02:37,040 --> 00:02:40,710 Let's examine the MathUtils class by taking a peek at its methods. 43 00:02:40,710 --> 00:02:44,989 We'll start by calling a method on the class object called, quite intuitively, 44 00:02:44,989 --> 00:02:45,741 GetMethods. 45 00:02:48,525 --> 00:02:53,515 So here, we'll get all declared methods and 46 00:02:53,515 --> 00:02:56,864 we will call that method that I just referenced. 47 00:03:02,853 --> 00:03:07,273 And since we're using the method class for the first time, we better import that, 48 00:03:07,273 --> 00:03:07,788 as well. 49 00:03:14,019 --> 00:03:18,503 This will be the starting point from which we can look at various characteristics of 50 00:03:18,503 --> 00:03:22,750 these methods, such as their modifiers, private, public, static, etc. 51 00:03:22,750 --> 00:03:26,850 The number of parameters and the return types among other things. 52 00:03:26,850 --> 00:03:29,760 You can find out what all your options are by checking out the JavaDocs for 53 00:03:29,760 --> 00:03:31,990 the method class on the Oracle website. 54 00:03:31,990 --> 00:03:33,680 I put a link to this in the teacher's notes. 55 00:03:34,830 --> 00:03:38,586 We'll focus here on the ones I just mentioned since they're a particular 56 00:03:38,586 --> 00:03:40,352 importance to us in this project. 57 00:03:40,352 --> 00:03:42,905 Let's loop over this array of methods, and 58 00:03:42,905 --> 00:03:47,170 display each of those pieces of information that I mentioned. 59 00:03:47,170 --> 00:03:49,710 I'll write a loop now that summarizes what we want to do. 60 00:03:51,791 --> 00:03:53,590 So here, we'll loop over the methods. 61 00:03:55,110 --> 00:03:58,142 We use our enhanced for loop, also called a for-each-loop. 62 00:04:03,139 --> 00:04:07,832 And let me include some comments here that displays what we intend to do. 63 00:04:07,832 --> 00:04:14,284 We'll display the method name, the parameter count, 64 00:04:14,284 --> 00:04:21,949 the return type, and the modifiers. 65 00:04:26,471 --> 00:04:28,430 Let's start with a method name. 66 00:04:28,430 --> 00:04:30,000 This one is pretty straightforward. 67 00:04:30,000 --> 00:04:33,970 We'll display a single line, and the method we need to use is called getName. 68 00:04:33,970 --> 00:04:38,472 So for this, I will display a formatted string with System.out.printf. 69 00:04:40,765 --> 00:04:43,940 I'll include a placeholder for the actual method name, 70 00:04:43,940 --> 00:04:45,735 as well as a new line character. 71 00:04:45,735 --> 00:04:50,652 I'll stick into that placeholder the results of m.getName. 72 00:04:53,541 --> 00:04:57,674 So that we don't go too far down a potentially error ridden path, 73 00:04:57,674 --> 00:04:59,950 let's run our code now. 74 00:04:59,950 --> 00:05:02,779 To do this, I'm first gonna pull up my console so 75 00:05:02,779 --> 00:05:06,794 I have plenty of room to see the output that my program is generating. 76 00:05:06,794 --> 00:05:11,958 Okay, we'll clear, we'll compile to the out 77 00:05:11,958 --> 00:05:17,511 directory with a class path as a source directory, 78 00:05:17,511 --> 00:05:22,819 and here is the Java file that we want to compile. 79 00:05:26,709 --> 00:05:27,910 Great! 80 00:05:27,910 --> 00:05:29,030 All compiles well. 81 00:05:29,030 --> 00:05:29,840 Let's run this thing! 82 00:05:31,160 --> 00:05:35,917 Using the Java command, I'll specify the class path as the out directory, and 83 00:05:35,917 --> 00:05:40,674 then include the fully qualified name that includes the package name of the main 84 00:05:40,674 --> 00:05:41,176 class. 85 00:05:45,652 --> 00:05:46,900 Cool! 86 00:05:46,900 --> 00:05:48,970 Look at all those methods. 87 00:05:48,970 --> 00:05:53,018 But, wait, I didn't declare all those methods in our MathUtils class. 88 00:05:54,050 --> 00:05:56,400 You probably already see what's happening in here. 89 00:05:56,400 --> 00:06:01,100 The methods that are returned when we call getMethods include not only the declared 90 00:06:01,100 --> 00:06:06,180 methods from the MathUtils class, but also inherited methods. 91 00:06:06,180 --> 00:06:09,430 Now, if we want to focus on the declared method and 92 00:06:09,430 --> 00:06:13,250 exclude things like toString and hashCode and getClass, 93 00:06:13,250 --> 00:06:18,290 we simply call a method that returns only declared methods. 94 00:06:18,290 --> 00:06:23,310 This one is called, again, intuitively getDeclaredMethods. 95 00:06:23,310 --> 00:06:26,770 And when we loop over those we'll see only methods that we 96 00:06:26,770 --> 00:06:29,320 put in the MathUtils class. 97 00:06:29,320 --> 00:06:32,721 Let's recompile and rerun our code to see the results. 98 00:06:37,331 --> 00:06:38,629 Clear before I run. 99 00:06:41,058 --> 00:06:42,390 And there we go. 100 00:06:42,390 --> 00:06:46,027 There are the five methods that are present in the MathUtils class. 101 00:06:47,750 --> 00:06:51,150 Next, let's display the number of parameters for each method. 102 00:06:51,150 --> 00:06:54,670 To accomplish this, we'll use the getParameterCount method which gives you 103 00:06:54,670 --> 00:06:57,930 exactly what you think it should, the number of parameters. 104 00:06:57,930 --> 00:07:00,651 I'll use formatted output here again to display the count. 105 00:07:08,187 --> 00:07:11,080 I'll include a tab character here just for nice formatting. 106 00:07:11,080 --> 00:07:15,260 I'll say the number of params, and then include a placeholder 107 00:07:15,260 --> 00:07:18,940 where we will stick the actual parameter count, as well as a newline character. 108 00:07:20,490 --> 00:07:26,982 Into that placeholder, I will stick m.getParameterCount. 109 00:07:26,982 --> 00:07:27,672 Capital C. 110 00:07:30,253 --> 00:07:33,524 Let's run it again and see if our output matches what we expect. 111 00:07:36,027 --> 00:07:39,831 I'll recompile. 112 00:07:39,831 --> 00:07:42,380 We'll clear, and we'll run again. 113 00:07:42,380 --> 00:07:43,060 And there we go, 114 00:07:43,060 --> 00:07:47,610 the number of parameters is correctly listed under each method name. 115 00:07:47,610 --> 00:07:48,140 Pretty cool. 116 00:07:50,150 --> 00:07:53,780 Another piece of information we can get from our methods using reflection is 117 00:07:53,780 --> 00:07:54,920 the return type. 118 00:07:54,920 --> 00:07:57,130 Let's display this in a similar fashion. 119 00:07:58,290 --> 00:08:02,118 So under Display return type, I will display another line of formatted output, 120 00:08:05,083 --> 00:08:09,130 Which includes, again, a tab character for a nicely formatted output. 121 00:08:09,130 --> 00:08:10,380 Here's the return type. 122 00:08:11,490 --> 00:08:14,900 My string placeholder and my new line character. 123 00:08:17,050 --> 00:08:21,551 And I'll stick into that placeholder the results of getReturnType. 124 00:08:25,211 --> 00:08:27,732 Let's recompile and rerun, see what we get. 125 00:08:30,241 --> 00:08:31,819 All compiles well. 126 00:08:31,819 --> 00:08:32,510 We clear. 127 00:08:34,190 --> 00:08:35,650 And I'll run again. 128 00:08:35,650 --> 00:08:36,500 And there we go. 129 00:08:36,500 --> 00:08:41,080 We get the return types for each one of our methods. 130 00:08:41,080 --> 00:08:44,480 Now, in the case of return types that are classes, the output contains the fully 131 00:08:44,480 --> 00:08:48,590 qualified name of the class, which means that it includes the package name. 132 00:08:48,590 --> 00:08:52,390 For example, here java.lang.Double. 133 00:08:52,390 --> 00:08:55,950 If you don't want that then you can get what's called the simple name. 134 00:08:55,950 --> 00:08:58,950 So I'll tack onto this return value here, and 135 00:08:58,950 --> 00:09:03,991 we'll use .getSimpleName. 136 00:09:03,991 --> 00:09:07,107 Let's recompile and rerun and see what our results are. 137 00:09:09,256 --> 00:09:11,550 Recompile, all clear, and rerun. 138 00:09:13,580 --> 00:09:15,640 Cool, much simpler return types there. 139 00:09:18,160 --> 00:09:20,800 The last piece of information about each method that we'll examine 140 00:09:20,800 --> 00:09:22,210 are the modifiers. 141 00:09:22,210 --> 00:09:25,460 This one's a big trickier than the others because when we call get modifiers in 142 00:09:25,460 --> 00:09:28,181 the method object, we actually get back an int value. 143 00:09:29,210 --> 00:09:32,590 Let's stick it into an int variable for now and I'll show you how we can 144 00:09:32,590 --> 00:09:37,050 convert this int into a string that represents all modifiers as you'd expect. 145 00:09:38,300 --> 00:09:44,780 So I'll create an int variable called mods and call getModifiers. 146 00:09:47,050 --> 00:09:49,295 Then, let's see what this output produces. 147 00:09:49,295 --> 00:09:53,876 System.out.printf, again, 148 00:09:53,876 --> 00:09:57,313 using my tab character. 149 00:09:57,313 --> 00:10:00,362 Here's a placeholder for the int modifier. 150 00:10:05,525 --> 00:10:07,640 We'll save that. 151 00:10:07,640 --> 00:10:10,950 Now, if we compile and run this program, you'll see those ints. 152 00:10:10,950 --> 00:10:11,927 Let's do that now. 153 00:10:18,811 --> 00:10:19,980 There they are. 154 00:10:19,980 --> 00:10:24,356 Modifiers 9, 9, 10. 155 00:10:24,356 --> 00:10:27,381 These aren't particularly meaningful to us, but 156 00:10:27,381 --> 00:10:31,108 if we use a convenience method provided by the modifier class, 157 00:10:31,108 --> 00:10:35,000 we can get a space separated string representing all modifiers. 158 00:10:36,690 --> 00:10:41,260 To do this, I'll add a line of code that includes a string variable called 159 00:10:41,260 --> 00:10:44,440 modString, or modStr as an abbreviation. 160 00:10:44,440 --> 00:10:48,672 And the modifier class includes a static method called toString that accepts 161 00:10:48,672 --> 00:10:52,020 a parameter, unlike the standard toString method. 162 00:10:52,020 --> 00:10:53,090 I'll pass to it the int. 163 00:10:54,240 --> 00:10:59,050 Now, if I swap out this for 164 00:10:59,050 --> 00:11:03,840 modString, I should see that modifier string that this static method produces. 165 00:11:03,840 --> 00:11:06,250 Now, I've just introduced a new class here, of modifier. 166 00:11:06,250 --> 00:11:10,290 So in order for this to compile, I know I'm gonna have to go up and import that. 167 00:11:10,290 --> 00:11:13,010 Let's go add that import statement now. 168 00:11:13,010 --> 00:11:18,343 Import java.lang.reflect.Modifier. 169 00:11:18,343 --> 00:11:24,347 And with that in place, let's compile our code. 170 00:11:24,347 --> 00:11:27,890 We'll clear, and rerun. 171 00:11:27,890 --> 00:11:28,550 There we go. 172 00:11:28,550 --> 00:11:32,050 We see those modifiers exactly as we would have expected them. 173 00:11:33,830 --> 00:11:36,370 Having practiced almost all of the reflection we'll need for 174 00:11:36,370 --> 00:11:39,930 coding the Doc Processor class, let's go there in the next video.