Java反射:获取类/接口属性的几个方法

java.lang.Class上有几个获取属性的方法:

  • getDeclaredField()
  • getDeclaredFields()
  • getField()
  • getFields()

public Field getDeclaredField(String name)

说明

  • 返回一个Field对象,该对象反映此Class对象所代表的类或接口的指定声明字段。名称参数是一个字符串,它指定所需字段的简单名称。
  • 只返回一个本Class中声明的属性(也包含私有属性)。
  • 不能获取从父类上继承来的属性。

示例:获取本Class上声明的属性

父类Bar:

package com.team.getclassobject.demo1;

public class Bar {
    private String nameInFather;
    protected boolean booleanInFather;
    String idInFather;
    public double scoreInFather;
}

子类Foo:

package com.team.getclassobject.demo1;

public class Foo extends Bar {
    
    private String nameInFoo;
    protected boolean booleanInFoo;
    String idInFoo;
    public double scoreInFoo;
}

测试类Demo:

package com.team.getclassobject.demo1;

import java.lang.reflect.Field;

public class Demo {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException {
        Class<?> c = Class.forName("com.team.getclassobject.demo1.Foo");
        Field f1 = c.getDeclaredField("nameInFoo");
        System.out.println(f1.toGenericString());
        
        Field f2 = c.getDeclaredField("idInFoo");
        System.out.println(f2.toGenericString());
        
        Field f3 = c.getDeclaredField("booleanInFoo");
        System.out.println(f3.toGenericString());
        
        Field f4 = c.getDeclaredField("scoreInFoo");
        System.out.println(f4.toGenericString());
    }

}

运行输出:
在这里插入图片描述

示例:获取父类上的属性失败

父类Bar:

package com.team.getclassobject.demo1;

public class Bar {
    private String nameInFather;
    protected boolean booleanInFather;
    String idInFather;
    public double scoreInFather;
}

子类Foo:

package com.team.getclassobject.demo1;

public class Foo extends Bar {
    
    private String nameInFoo;
    protected boolean booleanInFoo;
    String idInFoo;
    public double scoreInFoo;
}

测试类Demo:

package com.team.getclassobject.demo1;

import java.lang.reflect.Field;

public class Demo {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException {
        Class<?> c = Class.forName("com.team.getclassobject.demo1.Foo");
        Field f1 = c.getDeclaredField("scoreInFather");
        System.out.println(f1.toGenericString());
    }

}

运行结果:
在这里插入图片描述

public Field[] getDeclaredFields()

说明

  • 返回一个Field对象数组,该数组反映此Class对象所代表的类或接口声明的所有字段。这包括公共、受保护、默认(包)访问和私有字段,但不包括继承的字段

示例

父类Bar:

package com.team.getclassobject.demo1;

public class Bar {
    private String nameInFather;
    protected boolean booleanInFather;
    String idInFather;
    public double scoreInFather;
}

子类Foo:

package com.team.getclassobject.demo1;

public class Foo extends Bar {
    
    private String nameInFoo;
    protected boolean booleanInFoo;
    String idInFoo;
    public double scoreInFoo;
}

测试类Demo:

package com.team.getclassobject.demo1;

import java.lang.reflect.Field;

public class Demo {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException {
        Class<?> c = Class.forName("com.team.getclassobject.demo1.Foo");
        Field[] fs = c.getDeclaredFields();
        for (Field f : fs) {
            System.out.println(f.toGenericString());
        }
    }

}

运行结果:
在这里插入图片描述

public Field getField(String name)

说明

返回一个Field对象,该对象反射此Class对象所代表的类或接口的指定公共成员字段name参数是一个字符串,指定所需字段的简单名称。

要反射的字段由以下算法确定。设C为由此Class对象表示的类或接口:

  1. 如果C声明了一个具有指定名称的公共字段,则该字段是要反射的字段。
  2. 如果在步骤1中未找到字段,则将此算法递归应用于C的每个直接父接口。直接父接口按声明的顺序搜索。一直递推往上找,即直接父接口上没有找到,还会找父接口的父接口。
  3. 如果在步骤1和2中都未找到字段,并且C有一个父类S,则在此算法上递归调用S。一直递推往上找,即直接父类上没有找到,还会找直接父类的父类。如果C没有父类,则抛出NoSuchFieldException。

示例:获取本类上的公共属性成功

定义类Foo:

package com.team.getclassobject.demo1;

public class Foo {
    
    private String nameInFoo;
    protected boolean booleanInFoo;
    String idInFoo;
    public double scoreInFoo;
}

定义测试类Demo:

package com.team.getclassobject.demo1;

import java.lang.reflect.Field;

public class Demo {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException {
        Class<?> c = Class.forName("com.team.getclassobject.demo1.Foo");
        Field f = c.getField("scoreInFoo");
        System.out.println(f.toGenericString());
    }

}

运行结果:
在这里插入图片描述

示例:获取本类上的保护属性失败

定义类Foo:

package com.team.getclassobject.demo1;

public class Foo {
    
    private String nameInFoo;
    protected boolean booleanInFoo;
    String idInFoo;
    public double scoreInFoo;
}

定义测试类Demo:

package com.team.getclassobject.demo1;

import java.lang.reflect.Field;

public class Demo {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException {
        Class<?> c = Class.forName("com.team.getclassobject.demo1.Foo");
        Field f = c.getField("booleanInFoo");
        System.out.println(f.toGenericString());
    }

}

运行结果:
在这里插入图片描述

示例:获取到了直接父接口上的字段

下面示例中,要获取score这个字段,但本类没有定义,而直接父接口上定义了这个字段,所以获取到了。

父接口Inter1:

package com.team.getclassobject.demo1;

public interface Inter1 {

    double score = 99.0;
}

类Foo:

package com.team.getclassobject.demo1;

public class Foo implements Inter1 {
    
    private String nameInFoo;
    protected boolean booleanInFoo;
    String idInFoo;
    public double scoreInFoo;
}

测试类Demo:

package com.team.getclassobject.demo1;

import java.lang.reflect.Field;

public class Demo {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException {
        Class<?> c = Class.forName("com.team.getclassobject.demo1.Foo");
        Field f = c.getField("score");
        System.out.println(f.toGenericString());
    }

}

运行结果:
在这里插入图片描述

示例:要获取的字段在本类上不存在,但直接父类和直接父接口上都定义了,最终获得了直接父接口上的字段

下面示例中,要获取score这个字段,但本类没有定义,而直接父接口和直接父类上都定义了这个字段,获取到的是直接父接口上的字段。

直接父接口Inter1:

package com.team.getclassobject.demo1;

public interface Inter1 {

    double score = 99.0;
}

直接父类Bar:

package com.team.getclassobject.demo1;

public class Bar {
    public double score;
}

Foo类:

package com.team.getclassobject.demo1;

public class Foo extends Bar implements Inter1 {
    
    private String nameInFoo;
    protected boolean booleanInFoo;
    String idInFoo;
    public double scoreInFoo;
}

测试类Demo:

package com.team.getclassobject.demo1;

import java.lang.reflect.Field;

public class Demo {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException {
        Class<?> c = Class.forName("com.team.getclassobject.demo1.Foo");
        Field f = c.getField("score");
        System.out.println(f.toGenericString());
    }

}

运行结果:
在这里插入图片描述

示例:要获取的字段在本类上和直接父接口上都不存在,但直接父类定义了,最终获得了直接父类上的字段

下面示例中,要获取score这个字段,但本类和直接父接口上都没有定义,而直接父类上定义了这个字段,获取到的是直接父类上的字段。

直接父接口Inter1:

package com.team.getclassobject.demo1;

public interface Inter1 {
   
}

直接父类Bar:

package com.team.getclassobject.demo1;

public class Bar {
    public double score;
}

类Foo:

package com.team.getclassobject.demo1;

public class Foo extends Bar implements Inter1 {
    
    private String nameInFoo;
    protected boolean booleanInFoo;
    String idInFoo;
    public double scoreInFoo;
}

测试类Demo:

package com.team.getclassobject.demo1;

import java.lang.reflect.Field;

public class Demo {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException {
        Class<?> c = Class.forName("com.team.getclassobject.demo1.Foo");
        Field f = c.getField("score");
        System.out.println(f.toGenericString());
    }

}

运行结果:
在这里插入图片描述

示例:要获取的字段在本类上不存在,在爷爷接口(即父接口的父接口)定义了,最终获得了爷爷接口上的字段

下面示例中,要获取score这个字段,但本类没有定义,直接父类上定义了,直接父接口上没有定义,爷爷接口上定义了,最终获取到的是爷爷接口上的字段。

爷爷接口Inter2:

package com.team.getclassobject.demo1;

public interface Inter2 {
    double score = 90;
}

直接父接口Inter1:

package com.team.getclassobject.demo1;

public interface Inter1 extends Inter2 {
   
}

直接父类Bar:

package com.team.getclassobject.demo1;

public class Bar {
    public double score;
}

类Foo:

package com.team.getclassobject.demo1;

public class Foo extends Bar implements Inter1 {
    
    private String nameInFoo;
    protected boolean booleanInFoo;
    String idInFoo;
    public double scoreInFoo;
}

测试类Demo:

package com.team.getclassobject.demo1;

import java.lang.reflect.Field;

public class Demo {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException {
        Class<?> c = Class.forName("com.team.getclassobject.demo1.Foo");
        Field f = c.getField("score");
        System.out.println(f.toGenericString());
    }

}

运行结果:
在这里插入图片描述

示例:要获取的字段在本类上没有定义,在直接父类上也没有定义,在爷爷类上定义了,最终获得了爷爷类上的字段

下面示例中,要获取score这个字段,但本类没有定义,要获取的字段在本类上没有定义,在直接父类上也没有定义,在爷爷类上定义了,最终获得了爷爷类上的字段。

爷爷类GrandFather:

package com.team.getclassobject.demo1;

public class GrandFather {
    public double score;
}

父类Father:

package com.team.getclassobject.demo1;

public class Father extends GrandFather {
    
}

类Foo:

package com.team.getclassobject.demo1;

public class Foo extends Father {
    
    private String nameInFoo;
    protected boolean booleanInFoo;
    String idInFoo;
    public double scoreInFoo;
}

测试类Demo:

package com.team.getclassobject.demo1;

import java.lang.reflect.Field;

public class Demo {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException {
        Class<?> c = Class.forName("com.team.getclassobject.demo1.Foo");
        Field f = c.getField("score");
        System.out.println(f.toGenericString());
    }

}

运行结果:
在这里插入图片描述

public Field[] getFields()

说明

  • 返回一个包含Field对象的数组,这些对象反映此Class对象所代表的类或接口的所有可访问的公共字段。
  • 如果此Class对象代表的类或接口没有可访问的公共字段,则此方法返回一个长度为0的数组。
  • 如果此Class对象代表一个类,则此方法返回该类及其所有祖先类和祖先接口的公共字段。
  • 如果此Class对象代表一个接口,则此方法返回该接口及其所有祖先接口的字段。
  • 如果此Class对象代表一个数组类型、基本类型或void,则此方法返回一个长度为0的数组。
  • 返回数组中的元素不排序且没有特定顺序。

示例

爷爷类GrandFather:

package com.team.getclassobject.demo1;

public class GrandFather {
    public double score;
}

父类Father:

package com.team.getclassobject.demo1;

public class Father extends GrandFather {
    public int age;
}

类Foo:

package com.team.getclassobject.demo1;

public class Foo extends Father {
    
    private String nameInFoo;
    protected boolean booleanInFoo;
    String idInFoo;
    public double scoreInFoo;
}

测试类Demo:

package com.team.getclassobject.demo1;

import java.lang.reflect.Field;

public class Demo {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException {
        Class<?> c = Class.forName("com.team.getclassobject.demo1.Foo");
        Field[] fs = c.getFields();
        for (Field f : fs) {
            System.out.println(f.toGenericString());
        }
        
    }

}

运行输出:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值