Reflection question

Discussion in 'Plugin Development' started by lordbobby104, Feb 8, 2014.

Thread Status:
Not open for further replies.
  1. Offline

    lordbobby104

    Ok so I have two questions about reflection. I have seen it used a lot and it seems that it would be useful. So what is it and how is it used? If anybody could help or point me to a thread that explains this that would be great!
     
  2. Offline

    Icyene

    Reflection is a way to access and manipulate class members without knowing their name at compile-time. I've found that the Oracle tutorials on reflection do well at explaining what seems as a complex subject when you first delve into it.
     
  3. Offline

    Maurdekye

    lordbobby104 You may want to check here, there's a decent explanation about it in there somewhere.
     
  4. Offline

    xTrollxDudex

    lordbobby104
    This is not the place to ask for Java questions. Nevertheless, I will try my best to explain.

    Reflection is the branch or Java that deals with mirroring the Java classes during Runtime, there are Pros and Cons to using Reflection:
    Pros:
    - Acess private members of an API
    - Create flexibility within a member

    Cons:
    - Slow. JVM optimizations can't be performed using Reflection
    - Unsafe. The ability to access private members may break certain platforms.

    Alright, with the intro done, lets get straight to the point.

    There are 4 main members in the Java language:
    - Field
    - Constructor
    - Method
    - Class
    Each of these are accessible at ANY access level theough Reflection. Let's start wih Field.

    Imagine that we have a Key to something:
    PHP:
    public class Keys {
        private 
    Object key;
        public 
    Keys(Object key) {
            
    this.key key;
        }
    }
    We want to access it right? Right. Here is how we can get the Key:
    PHP:
    Key key = new Key(new Object());
    Field field key.getClass().getDeclaredField("key");

    Object keys;
    try { 
        
    field.setAccessible(true);
        
    keys field.get(key);
    } catch (
    Exception x) {
        
    x.prinstStackTrace();
    }
    In this case, we have an object declaration to refer back to, we have a Keys object to reference.
    Then, we get the field. getClass() grabs the objective class, and is programatically equivalent to
    PHP:
    Keys.class.getDeclaredField("key");
    we have getDeclaredField. The difference between this and ANY method that:
    - Is get<Member>
    - Compared to getDeclared<Member>
    Is the former gets all PUBLIC members from the class AND it's superclass. The latter gets ALL fields, at ANY level of access from the explicitly declared class that will be of origin.
    The String parameter is the field name.

    Then, we use the get method. This method requires an Object parameter for the instance of the field container we are getting.

    Now to methods and constructors.
    They are almost the same except for the way we get them.
    Imagine our Keys class again:
    PHP:
    public class Keys {
        private 
    Object key;

        
    // Supress default construction
        
    private Keys() { }
        private 
    Keys(Object key) {
            
    this.key key;
        }
        private 
    Object getKey() {
            return 
    this.key;
        }
    }
    See the issue? All the members are PRIVATE!

    No problemo, use Reflection!
    PHP:
    Constructor<?Keys.class.getDeclaredConstructor(Object.class);
    Method m Keys.class.getDeclaredMethod("getKey");

    Object keys;
    try { 
        
    c.setAccessible(true);
        
    m.setAccessible(true);

        
    Keys key = (Keysc.newInstance(new Object());
        
    keys m.invoke(key);
    } catch (
    Exception x) {
        
    x.prinstStackTrace();
    }
    Here we are introduced to a new limit of Reflection: All Objects returned from a Reflective operation are generic Object(s). You will need an unchecked cast to the specified object in order to get the actual instance of it from a Reflective operation, as see when I cast to Keys when I do newInstance on the Constructor.

    This instroduces you also to Parameterized Classes, which an example is te Constructor<?> parrt. ? Is a wildcard in Java, used when you don't actually know what the Object is. Objects of different parameters cannot be casted together AFAIK. You can put Types in there such as
    PHP:
    Constructor<Keys>
    Which helps with a concept called Type Safety, deeper into Java.

    Again, we see a getDeclared<Member>, and this time, we use the Keys.class syntax instead of getClass. Why? We don't actually have an instance of Keys yet, so we need a direct class reference.

    Constructor takes a dynamic class parameter for the parameter classes.
    Say you have a constructor like so:
    PHP:
    public Constructor(int iString s) {
        
    // ...
    }
    You need to do:
    PHP:
    Constructor<?= <Class>.class.getDeclaredConstructor(int.class, String.class);
    See where it is going?

    Method is exactly the same, but sticks the METHOD NAME in front of the dunamic parameter types:
    PHP:
    public fooBar(String sdouble d) {
        
    // ....
    }
    This would get it:
    PHP:
    Method m = <Class>.class.getDeclaredMethod("fooBar"String.class, double.class);
    See?
    And yes, all Primitive Types doe have classes.

    Now classes. You can get a class like so:
    PHP:
    package foo.bar.test;

    public class 
    Test {}
    Using:
    PHP:
    Class<?clazz = Class.forName("foo.bar.test.Test");
    You can use the clazz to get all kinds of members as a shorcut:
    PHP:
    clazz.getDeclaredField(/* ... */);
    As an example.

    Notice how Class also has a Type Parameter.

    Class.forName takes a Fully Qualified Name of the class, which includes the package, and then containing class, if it exists first. Then the name. The actual static method does not need a Type to prefix it. Doing so will error:
    PHP:
    // DO NOT DO!
    Class<?clazz = Class<?>.forName("foo.bar.test.Test");
    I haven't done much with classes yet, have no idea how to get local classes.

    Hopefully, this post helps you a bit more with Java and its Reflection API. Please don't hesitate to ask questions if you are *confuzzled* by something!
     
    FisheyLP and Gater12 like this.
  5. Offline

    lordbobby104

    xTrollxDudex I have just recently been seeing the word reflection a lot when looking through NMS posts. I didn't realize it was a have thing too :p. It seem complicated but I think a little research wouldn't hurt. Thanks for the post! I now actually know what it is :p
     
Thread Status:
Not open for further replies.

Share This Page