检查类修饰符和类型(Examining Class Modifiers and Types)

   一个类可能被声明为包含该一个或者多个影响它运行时行为的修饰符。

  • 访问权限修饰符:public,protected和private
  • 需要重写修饰符:abstract
  • 限制一个实例修饰符:static
  • 禁止值修改:final
  • 强制浮点型行为:strictfp
  • 注解

   不是所有的修饰符可以使用到所有的类上面,比如,一个接口不能被修饰为final,一个枚举不能被修饰为abstract。java.lang.reflect.Modifier包含所有存在修饰符的声明,它同样包含用来解析Class.getModifiers()返回的修饰符集合。

   例子ClassDeclaration展示了怎么获取一个类的描述信息,包括修饰符、泛型类型、实现接口和继承路径,由于Class实现AnnotatedElement接口,它也可以查询运行时注解。

import java.lang.annotation.Annotation;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
import static java.lang.System.out;

public class ClassDeclarationSpy{
    public static void main(String... args){
        try{
            Class<?> c = Class.forName(args[0]);
            out.format("Class:%n %s%n%n",c.getCanonicalName());
            out.format("Modifiers:%n  %s%n%n", Modifier.toString(c.getModifiers()));
            out.format(Type Parameters:%n);
            TypeVariable[] tv = c.getTypeParameters();
            if(tv.length !=0){
                out.format(" ");
                for(TypeVariable t:tv){
                    out.format("%s ", t.getName());
                }
            }else{
                out.format("  -- No Type Parameters --%n%n");
            }
            out.format("Implemented Interfaces:%n");
            Type[] intfs = c.getGenericInterfaces();
            if(intfs.length != 0){
                for(Type intf : intfs){
                    out.format("  %s%n", intf.toString());
                }
                out.format("%n");
            }else{
                out.format("  -- No Implemented Interfaces --%n%n");
            }
                out.format("Inheritance Path:%n");
        List<Class> l = new ArrayList<Class>();
        printAncestor(c, l);
        if (l.size() != 0) {
        for (Class<?> cl : l)
            out.format("  %s%n", cl.getCanonicalName());
        out.format("%n");
        } else {
        out.format("  -- No Super Classes --%n%n");
        }
        out.format("Annotations:%n");
        Annotation[] ann = c.getAnnotations();
        if (ann.length != 0) {
        for (Annotation a : ann)
            out.format("  %s%n", a.toString());
        out.format("%n");
        } else {
        out.format("  -- No Annotations --%n%n");
        }
        }catch(ClassNotFoundException x){
            x.printStackTrace();
        }
    }
    private static void printAncestor(Class<?> c,List<Class> l){
        Class<?> ancestor = c.getSuperClass();
        if(ancestor != null){
            l.add(ancestor);
            printAncestor(ancestor,l);
        }
    }

}

   举一些输出例子,斜体字为输入参数。

$ *java ClassDeclarationSpy java.util.concurrent.ConcurrentNavigableMap*
Class:
    java util.concurrent.ConcurrentNavigableMap
Modifiers:
    public abstract interface
Type Parameters:
    K V
Implemented Interfaces:
    java.util.concurrent.ConcurrentMap<K,V>
    java.util.NavigableMap<K,V>
Inheritance Path:
    --No Super Classes --
Annotations:
    --No Annotations --

这是给java.util.concurrent.ConcurrentNavigableMap实际的声明,在这个代码中:

public interface ConcurrentNavigableMap<K,V> extends ConcurrentMap<K,V>,NavigableMap<K,V>

   注意,由于这个是一个接口,隐藏包含abstract,编译器会给每个接口添加这个修饰符,同时,这个声明包含了两个泛型参数,K和V,样例代码简单的打印这些参数,但是获取额外的关于在java.lang.reflect.TypeVariable中方法的信息。接口同样可以实现其它接口,如:

$ java ClassDeclarationSpy "[Ljava.lang.String;"
Class:
    java.lang.String[]
Modifiers:
    public abstract final
Type Parameters:
    -- No Type Parameters --
Implemented Interfaces:
    interface java.lang.Cloneable
    interface java.lang.Serializable
Interitance Path:
    java.lang.Object
Annotations:
    -- No Annotations --

   由于数组是运行时对象,他们所有的类型信息由java虚拟机定义,尤其,数组实现Cloneable和java.io.Serializable和其它直接父类。

$ java ClassDeclarationSpy java.io.InterruptedIOException
Class:
    java.io.InterruptedIOException
Modifiers:
    public
Type Parameters:
    -- No Type Parameters --
Implemented Interfaces:
    -- No Implemented Interfaces --
Inheritance Path:
    java.io.IOException
    java.lang.Exception
    java.lang.Throwable
    java.lang.Object
Annotations:
    -- No Annotations --

   从继承路径,可以推断出java.io.InterruptedIOException是一个受检异常类型,因为RuntimeException是它的父类。

$ java ClassDeclarationSpy java.security.Identity
Class:
    java.security.Identity
Modifiers:
    public abstract
Type Parameters:
    -- No Type Parameters --
Implemented Interfaces:
    interface java.security.Principal
    interface java.io.Serializable
Interitance Path:
    java.lang.Object
Annotations:
    @java.lang.Deprecated()

   这个输出展示了java.security.Identity是一个废弃api,含有java.lang.Deprecated注解,这个可能用于反射代码来检查废弃apis

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值