ホームページ  >  記事  >  Java  >  Java では、リフレクションによるクラス情報の取得が導入されています

Java では、リフレクションによるクラス情報の取得が導入されています

coldplay.xixi
coldplay.xixi転載
2021-02-26 10:36:492322ブラウズ

Java では、リフレクションによるクラス情報の取得が導入されています

無料学習の推奨事項: Java 基本チュートリアル

Directory

    ##1. フィールドの取得
  • ##2. フィールドの逆コンパイル
  • ##3. リフレクション メカニズムを介したオブジェクト プロパティへのアクセス
  • ## 4.可変長パラメータ
  • 5. リフレクション メソッド (理解)
  • 6. デコンパイル (理解)
  • 7. メソッドを呼び出すリフレクション メカニズム
  • 8. リフレクション コンストラクター
  • 9. リフレクション メカニズムはコンストラクターを呼び出します
  • 10. 親クラスと親インターフェイスを取得します
  • 前のセクションでリフレクション メカニズムを紹介しました。リフレクションの仕組みについて説明します。このセクションでは、リフレクションを通じてクラスの属性、メソッド、その他の情報を取得する方法を紹介します。
1. フィールドの取得

public class ReflectTest03 {
    public static void main(String[] args) throws Exception{
        //1.获取整个类
        Class studentClass=Class.forName("cn.yujie.bean.Student");
        String className=studentClass.getName();
        System.out.println(className);
        System.out.println(studentClass.getSimpleName());

        //获取类中的所有public的Field
        Field[] fields=studentClass.getFields();
        System.out.println(fields.length);      //测试数组中只有1个元素
        //测试这个field
        Field f=fields[0];
        //取出field的它的名字
        String fieldName=f.getName();
        System.out.println(fieldName);

        //获取所有的Field
        //获取所有的Field
        Field[] fs=studentClass.getDeclaredFields();
        System.out.println(fs.length);
        System.out.println("-----------------");
        //遍历
        for(Field field :fs){
            //获取属性的修饰符列表
            //返回的修饰符是一个数字,每个数字是修饰符的代号
            int i=field.getModifiers();
            //可以将这个代号数字转换成字符串
            String ModifierString = Modifier.toString(i);
            System.out.print(ModifierString+" ");
            //获取属性的类型
            Class fieldType=field.getType();
            String fName=fieldType.getSimpleName();
            System.out.print(fName+" ");
            //获取属性的名字
            System.out.println(field.getName()+" ");
            System.out.println();
        }
    }}

2. フィールドの逆コンパイル

リフレクション メカニズムを通じてクラスの属性を逆コンパイルします。

public class ReflectTest05 {
    public static void main(String[] args) throws Exception{
        //创建这个是为了拼接字符串
        StringBuilder s=new StringBuilder();
        Class studentClass=Class.forName("cn.yujie.bean.Student");
        s.append(Modifier.toString(studentClass.getModifiers())+" class "+studentClass.getSimpleName()+"{");
        Field[] fields=studentClass.getDeclaredFields();
        s.append(";\n");
        for(Field field:fields){
            s.append("\t");
            s.append(Modifier.toString(field.getModifiers()));
            s.append(" ");
            s.append(field.getType().getSimpleName());
            s.append(" ");
            s.append(field.getName());
            s.append(";\n");
        }
        s.append("}");
        System.out.println(s);
    }}

3. リフレクション メカニズムを介してオブジェクト プロパティにアクセスするJava では、リフレクションによるクラス情報の取得が導入されています

マスターする必要があります:使い方リフレクション メカニズム オブジェクトのプロパティにアクセスします。


プロパティに値を割り当てます。set
プロパティの値を取得します。get

public class ReflectTest07 {
    public static void main(String[] args) throws Exception{

        Class studentClass=Class.forName("cn.yujie.bean.Student");
        //使用反射机制,怎么取访问一个对象的属性
        Object obj=studentClass.newInstance();  //obj就是student对象(底层调用无参数构造方法)
        //获取no属性(根据属性的名称获取Field)
        Field noFiled=studentClass.getDeclaredField("no");
        //给obj对象(Student对象)的no属性赋值
        //s.no=111;         //给s对象的no属性赋值111,三要素,对象,属性和值
        //虽然使用了反射机制,但是三要素还是缺一不可
        //注意,反射机制让代码复杂了,但是为了一个灵活,这也是值得的。
        noFiled.set(obj,222);           //给obj对象的no属性赋值222
        //读取属性的值
        //两个要素:获取obj对象no属性的值
        System.out.println(noFiled.get(obj));
        //可以访问私有属性吗
        Field nameField=studentClass.getDeclaredField("name");
        //打破封装(反射机制的缺点:打破封装,可能会给不法分子留下机会)
        nameField.setAccessible(true);
        //给name属性赋值
        nameField.set(obj,"jackson");
        //获取name属性的值
        System.out.println(nameField.get(obj));

    }}

4. 可変長パラメータ

可変長パラメータint... argsこれは可変長パラメータです

構文は次のとおりです: type... (注: 3 つのドットである必要があります)
1. 可変長パラメータに必要なパラメータの数は 0 ~ n です

2. 可変長パラメータは最後の位置にある必要がありますパラメータリストに含まれており、変数です。 長さパラメータは 1 つだけでなければなりません。
  • 3. 可変長は配列とみなすことができます。
  • public class ArgumentsTest {
        public static void main(String[] args) {
          m();
          m(10);
          m(20,40);
          //m("abc");编译错误
          m3("ab","cd","def","de9");
          String [] strs={"a","b","c"};
          m3(strs);
        }
        public static void m(int... args){
    
        }
        //必须在最后一个,且只有1个//    public static void m2(String... args1,int...args2){////    }
        public static void m3(String ...args){
            //可以将可变长度参数当成一个数组来看
            for(int i=0;i<args.length></args.length>
  • 5. 反映方法 (理解する) )
public class ReflectTest08 {
    public static void main(String[] args) throws Exception{
        //获取类了
        Class userServiceClass = Class.forName("cn.yujie.service.UserService");
        //获取所有的Method(包括私有的)
        Method[] methods=userServiceClass.getDeclaredMethods();
        System.out.println(methods.length);         //2
        //遍历Method
        for(Method method:methods){
            //获取修饰符列表
            System.out.println(Modifier.toString(method.getModifiers()));
            //获取方法的返回值类型
            System.out.println(method.getReturnType().getSimpleName());
            //获取方法名
            System.out.println(method.getName());
            //方法的参数列表(一个方法的参数可能有多个)
            Class[] parameterTypes=method.getParameterTypes();
            for(Class parameterType:parameterTypes){
                System.out.println(parameterType.getSimpleName());
            }
        }

    }}

6. 逆コンパイル (理解)

public class ReflectTest09 {
    public static void main(String[] args) throws Exception{
        StringBuilder s=new StringBuilder();
        Class userServiceClass = Class.forName("cn.yujie.service.UserService");
        s.append("public class UserService{ ");
        s.append(Modifier.toString(userServiceClass.getModifiers())+"class "+userServiceClass.getSimpleName()+"{ "+"\n");
        Method[] methods=userServiceClass.getDeclaredMethods();
        for(Method method:methods){
            s.append("\t");
            s.append(Modifier.toString(method.getModifiers()));
            s.append(" ");
            s.append(method.getReturnType().getSimpleName());
            s.append(" ");
            s.append(method.getName());
            s.append("(");
            //参数列表
            Class[] parameterTypes = method.getParameterTypes();
            for(Class parameterType:parameterTypes){
                s.append(parameterType.getSimpleName());
                s.append(",");
            }
            s.append("){}\n");
        }
        //删除指定下标位置上的字符
        s.deleteCharAt(s.length()-1);
        s.append("}");
        System.out.println(s);
    }}

7. メソッド呼び出しのリフレクション機構

キーポイント: リフレクション メカニズムのメソッドを介してメソッドを呼び出す方法をマスターする必要があります。 リフレクション メカニズムにより、コードの汎用性が高まります。将来構成ファイルを変更すると、作成されるオブジェクトや呼び出されるメソッドも異なりますが、Java コードを変更する必要はまったくありません。それがリフレクションの魅力です。

public class ReflectTest10 {
    public static void main(String[] args) throws Exception{
        //通过反射机制调用方法
        Class userServiceClass = Class.forName("cn.yujie.service.UserService");
        //创建对象
        Object obj=userServiceClass.newInstance();
        //java中有重载,java中通过方法名和形参来区分方法
        Method loginMethod=userServiceClass.getDeclaredMethod("login",String.class,String.class);
        //调用方法
        //调用方法有几个要素
        //要素1:对象,要素2:方法名,要素3:参数列表,要素4:返回值
        //反射机制中最重要的一个方法:必须记住
        //四要素
        /*
        loginMethod方法,obj对象
        admin,123是参数列表,retValue是返回值
        * */
        Object retValue=loginMethod.invoke(obj,"admin","123");
    }}

8. リフレクション コンストラクター

public class ReflectTest11 {
    public static void main(String[] args) throws Exception{
        StringBuilder s=new StringBuilder();
        Class vipClass=Class.forName("cn.yujie.bean.Vip");
        s.append(Modifier.toString(vipClass.getModifiers()));
        s.append(" class ");
        s.append(vipClass.getSimpleName());
        s.append("{\n");
        //拼接构造方法
        Constructor[] constructors=vipClass.getDeclaredConstructors();
        for(Constructor constructor:constructors){
            s.append("\t");
            s.append(Modifier.toString(constructor.getModifiers()));
            s.append(" ");
            s.append(vipClass.getSimpleName());
            s.append("(");
            Class[] parameterTypes=constructor.getParameterTypes();
            for(Class parameterType:parameterTypes){
                s.append(parameterType.getSimpleName());
                s.append(",");
            }
            if(parameterTypes.length>0) {
                s.deleteCharAt(s.length() - 1);
            }
            s.append("){}\n");
        }
        s.append("}");
        System.out.println(s);
    }}

9. リフレクション メカニズムはコンストラクターを呼び出します

public class ReflectTest12 {
    public static void main(String[] args) throws Exception{
        //使用反射机制怎么创建对象
        Class vipClass=Class.forName("cn.yujie.bean.Vip");
        //调用无参构造方法
        Object obj= vipClass.newInstance();
        //调用有参数构造方法
        //第一步:先获取到有参数构造方法
        Constructor con=vipClass.getDeclaredConstructor(int.class,String.class,String.class,boolean.class);
        //第二步:调用构造方法new对象
        Object newObj=con.newInstance(110,"jackson","1999-10-11",true);
        System.out.println(newObj);
    }}

10. 親クラスと親インターフェイスを取得する

Java では、リフレクションによるクラス情報の取得が導入されています

public class ReflectTest13 {
    public static void main(String[] args) throws Exception {
        //String举例
        Class stringClass=Class.forName("java.lang.String");
        //获取String的父类
        Class superClass=stringClass.getSuperclass();
        System.out.println(superClass.getSimpleName());
        //获取String类实现的所有接口
        Class[] interfaces=stringClass.getInterfaces();
        for(Class in:interfaces){
            System.out.println(in.getName());
        }
    }}

関連する無料学習の推奨事項:

Java の基礎

以上がJava では、リフレクションによるクラス情報の取得が導入されていますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。