Java Reflection Explained

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
java's reflection api allows you to write a program that can look at itself and even change itself while it's running you can kind of think of it as meta programming now before we get started use reflection at your own risk it's incredibly powerful and allows you to break all the rules of your program and of course with great power comes great responsibility now with that said let's go cause some trouble first though here's an experience i know you've all had you do a search for a simple programming problem you're having like convert timestamp to date java first thing you have to do is scroll down to the stack overflow result because that's the one you really wanted in the first place then you have to click to open up the stack overflow page and then you have to scroll down past the question because you don't care about that to get to what you really want the top answer then you have to highlight and copy the code from that answer so that you can borrow it for your own program but recently i discovered a new search engine called neva let me show you how that exact same thing works with neva so here's the stack overflow result but instead of just giving you a link it literally puts the top answer to that question right here on the search results page and not only that here's the code that goes along with that top answer complete with a button to copy it and you've already gotten what you're looking for this is just one tiny sliver of what neva offers neva puts you back in control of your search how does it do that well first neva is 100 ad free that's right no ads not only does that mean a way less annoying and intrusive search experience but it also means that all the results you see are 100 real organic results no one can pay to decide what you're allowed to see your data also stays completely private with neva your data is never sold to anyone ever and the neva extension even blocks other sites from tracking you it even comes with a premium vpn bitdefender and a world-class password manager lastpass premium so go check out the special link down in the description below right now exclusively for coding with john viewers to get neva premium absolutely free for one full month or go to neva.com codingwithjohn now let's get to it so first of course what is reflection well reflection is where your code can look at itself already made that joke to examine and change basically any element of any java class right in the middle of your running program so as usual let's start with an example so this is a pretty basic java class called cat and you've probably seen me use something similar a time or two before it has two private instance variables a name and an age it has a constructor that takes in the name and the age to create a new cat and it also has a handful of methods you can call it has a getter for the name and a getter and a setter for the age and then a few other methods down here that just print stuff out for demonstration purposes we have a public method a private method and then a public static method and a private static method so let's hop over to our main method and show how we can use reflection to peek into the structure of that cat class so first let's just go ahead and create a new cat object so we'll say cat my cat equals new cat and we need to pass in a name and an age so we'll pass in stella and six to start out let's see if we can just get all of the fields that are declared inside that cat class so in our case that would be this string name and int age now when you're using reflection to try and get some information about some objects class the first thing you're going to want to do is get that object's class by calling getclass on it so mycat.getclass this getclass method call is your window into a ton of reflection capabilities that java offers and to get a glimpse at all the reflection tools that are available to you just hit dot after get class now there's a lot here and it can get really confusing real quick so let's try not to get too overwhelmed by that right now and we'll just focus on trying to get all the fields that are in that cat class so to get all of the fields that are declared inside that cat class we can call get declared fields now if we hover over this we can see that it returns an array of type field so what we can do is put that array that it returns into a variable so we'll just create a an array of fields we'll call it cat fields and set that equal to the result of this method call and we'll go ahead and import this field the import that we want is java.lang.reflect so now that we have this array of field objects we can loop through them like we would any other array and we can use a for each loop so for field field in cat fields so for each one of those let's just just print out that field's name so to do that all we have to do is just print out field dot get name so let's go ahead and run that and see what it prints out for us okay so it prints out name and age so no big surprises there it did pretty much what we expected it to do but that's kind of cool right i mean we can write code that can actually see the structure of our java class but here's where it starts to get crazy so back over here in our cat class we have this string name field and it is private that means from outside of this class we have no access to this variable we can't view it and we certainly can't change it to some other value and so a lot of times when a variable is private you have things like accessor and mutator methods getters and setters that allow you to view and manipulate that value so in this class we do have a public get name method that returns the name so you can get its value but we don't have a setter for the name so you can't set that value from outside the class the only time it can ever be set is right here in the constructor so when you create a cat object you can set its name but you're never allowed to set its name to anything else at any other time and not only is it private it's also final which means that even if we did have the ability to set it from outside this class once it is set it can never be set to anything else so quickly to demonstrate that back over here in our main method if we take this mycat object which we've initially given the name stella because we can set the name in the constructor if we try and take this my cat and set the name on it to something else like fred it doesn't even compile because it says hey name has private access in that class we aren't allowed to do this and as i mentioned before we don't have a setter for the name either so we can set the age but we can't set the name to something else so we have absolutely no way to change a cat object's name from here in rma method but with reflection all of those rules that i just mentioned go completely out the window without making any changes at all to the actual source code of our cat class we can use reflection to force java to change the name of our cat so here's exactly how you can do that okay so in our program we're already gathering all of the fields that exist inside our cat class and we're looping through each of those fields so now what we want to do is inside this loop we want to look for the individual field that you're interested in which in our case is the name field so what we can say is if field dot get name dot equals the name of the field we're looking for which is name okay so what do we want to do once we find the right field well there's a method we can call on this field called field dot set now this set method actually takes two parameters the first parameter is the object that you want to set that field on so in our case we want to set a name on our my cat object so the object that we want to pass in for our first parameter is just my cat and the next parameter is the value that you want to set that field to so this will be the name that we want to give our cat so let's try to give him the name jimmy mcgill now when you call this set method java makes you handle an exception that it could throw so this is called a checked exception check out my other video on checked and unchecked exceptions if you want to learn more about that but for now i'm just going to go ahead and add a throws declaration here in the method signature okay so now we've got code that is attempting to set the name field on our mycat object to something else let's go ahead and run it and see what happens okay so we do get an exception we get an illegal access exception because we aren't allowed to change a field with modifiers private and final well i guess that's it right end of the road uh even with reflection i guess there's no way to do it of course yes there is a way to do it so here's what you do if you want to get around this pesky hey that field's private and final so you aren't allowed to manipulate a thing so all you have to do is say hey java take that field and make it so it is accessible to me by calling set accessible and passing in true and now if we run our program no exceptions at all but did it actually work did we successfully change the name of our cat let's go ahead and find out so after this for loop our cat's name should be changed so let's go ahead and print it out by just printing out my cat dot get name here we go and poof our cat is now jimmy mcgill the field was private it was final it had already been set to something else and we changed it anyway but of course all this reflection stuff is not just limited to fields you can do similar sorts of things with methods you can get all the methods that are declared inside a class pretty much the same way that we got all the fields that are declared so you can just call dot mycat.getclass.get declared methods and just like get declared fields returned a field array get declared methods returns a method array so we'll call it cat methods and set it equal to the result of our method call here and we need to import this method class which is just java.lang.reflect method first let's just make sure this is working how we expect so let's go ahead and loop through all of our methods with another for loop so for method method in cat methods so for each one of those let's just print out its name to make sure it's working method dot get name here we go okay so it's printing out all the methods that are declared in that class we've got get name this is a public static method set age hey this is private etc etc now you might notice they don't seem to be in any particular order and that's why you always have to loop through them to identify the individual one that you want to work with now one of the really cool things that you can do with a method object is you can execute that method so for example one of the methods in our cat class is just called meow so let's see if we can use reflection here to trigger our meow method so up here in our for loop the first thing we want to do is look for the meow method in our array so if method dot get name dot equals meow now to invoke this method we will actually call method dot you guessed it invoke and this takes parameters that are very similar to when we were calling this set method here the first parameter that it takes is the object that we want to call this method on in our case we want to call the method on our mycat object now in our case this meow method in the cat class doesn't take any parameters so let's actually go and take a look at that meow method here you can see that it's just a public void method and it doesn't take any parameters so then back over here where we're using reflection to invoke that method we don't have to have any other parameters to this invoke call however if the meow method did have parameters all we would need to do is add them in the same order that they need to be passed in here where we're calling the invoke method but since we don't have any we don't have to worry about it i'm also going to go ahead and get rid of these other extra print statements okay so now if we run our code it should call the meow method on our mycat object so let's see okay so it printed out meow and if we go back over to our cat class to our meow method that's exactly what it does so it is successfully calling that method using reflection now in this case this is not particularly impressive right i mean this is a public method we could have just directly called the meow method on our my cat object without using reflection and for public methods where we don't need to use reflection that's what we should have done so to get the exact same outcome without using reflection we could have just called mycat.meow and if we go ahead and run the program you know we get the exact same thing but what if instead you wanted to invoke a private method that you don't have access to here so if we go back over to our cat class we have a private method called hey this is private and so right now if we go back and try to call that hey this is private method on our mycat we get an error that says hey this is private is private you can't call it from here however we can try and call that same method using reflection so instead of looking for the meow method let's have it look for the hey this is private method now if we go ahead and try and run this as is so similar to how we were trying to set the private field before when we try to call a private method even using reflection we get an illegal access exception however the fix for that is also basically identical to what it was for the field so to make it so we can access this method here with reflection we can just call dot set accessible to true so now when we run our program we are able to successfully call that private method from here using reflection one other good thing to know here so you know how when we call this invoke method we have to pass in the object that we want to invoke that method on however some methods are static which means that you don't need an individual object of that class to be able to call that method so if we hop over to our cat class we have an example of a couple of static methods one of them here is called this is a public static method so back here where we're using reflection if we want to be able to call that this is a public static method method without needing a specific cat object all you have to do is pass in null for this parameter here and then if you go ahead and run it it pretty much does what you would expect and also as you might expect this same thing works for a private static method so back here in our cat class we have another method that is private and static and if we try and call that method with reflection as long as we set accessible to true first it works exactly the same way so all of this is pretty cool right it's pretty neat to be able to use reflection and and kind of get a bird's eye view of your program and manipulate things to be able to do whatever you want to do but it kind of leads to a question why would you use this a one reason is it's just really cool it's fun to play around with all the different methods that are available to you and see how you can manipulate your programs on top of that playing around with this for a little bit kind of helps to sink in a little bit of understanding about how some different parts of java work besides that though in the real world reflection is heavily used in things like frameworks the spring framework for example uses reflection all over the place because it has to be compatible with code that hasn't even been written yet when you use a tool like spring it uses reflection to look at all the classes that you've written in your own code and also uses reflection to create objects of those classes and manipulate them and inject them into other classes all that stuff is way more complicated than what we've done here but it uses the same basic tools you also occasionally might have to use reflection to do something a little bit more basic for example occasionally when i'm testing some class that class will have a private field that changes how all of the methods inside that class works and for testing i want to be able to set that private field and then make sure all the methods do what they're supposed to do in situations like that you can use reflection like we did here to force java to set that value however there are definitely downsides of reflection that you need to be aware of the first thing is obviously it's way easy to break everything using reflection if you don't know exactly what you're doing you can create some really wacky bugs that are really really tough to nail down as just a quick example so down here we're using reflection to you know explicitly call this method using its name but if you happen to be you know just a normal developer doing your job and you're going through this cat class and you suddenly say oh you know i see this method here but i think i have a better name for this method so i'm going to go ahead and use you know the ide tools like i should in order to change this method its name um so i can say new method name so this is a completely innocent change to make right it's a private method i can see that oh it's not being used anywhere else in the code obviously it's private so no problem at all but now if i go back over here to our main method and run our program it doesn't do anything at all because the name of that method changed now this if statement is never triggered it never finds that method because it doesn't exist anymore so now our code is just quietly working in a completely different way and it would be a hundred percent unexpected for somebody who's just making an innocent change like that another not so good thing about reflection is because it has to figure out and manipulate all this stuff at runtime it can't do any compile time optimizations so because of that code that uses reflection is usually way slower than code that does the same thing without reflection so with all that said when should you use reflection and when should you not a good rule of thumb is if you can possibly do something without reflection it's best to avoid using it your code will be faster more robust more testable and generally just easier and more pleasant to work with but there are plenty of legitimate uses that we did talk about so if you have to it's a really good tool to have on your tool belt or if you're just some kind of evil reflection genius and you just want to make the world suffer you can do that too if you enjoyed this video or learned something please be sure to like and subscribe it's the best way to make sure that these videos get out to help more people i also have a full java course available in a link down in the description below so if you're interested go check it out it's an amazing way that you can support the channel and get a ton of value and java knowledge in return as always thank you so much for watching i really do appreciate you being here with me and i'll see you next time
Info
Channel: Coding with John
Views: 84,078
Rating: undefined out of 5
Keywords: java, codingwithjohn, coding with john, java beginner lesson, java reflection, java reflection tutorial, reflection api, introduction to java reflection, java reflection video tutorial, java reflection api, java reflection explained, java reflection example, reflection api in java, java reflection api tutorial, coding with john java, learn java
Id: bhhMJSKNCQY
Channel Id: undefined
Length: 20min 7sec (1207 seconds)
Published: Mon Aug 29 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.