JavaSE(十一)反射机制与注解

JavaSE(十一)反射机制与注解



提示:以下是本篇文章正文内容,下面案例可供参考

一、反射(reflect)

反射机制相关类
1.java.lang.reflect.*;
2.java.lang.Class						代表整个字节码
3.java.lang.reflect.Method				代表字节码中的方法字节码
4.java.lang.reflect.Constructor			代表字节码中的构造方法字节码
5.java.lang.reflect.Field				代表字节码中的属性字节码

1.获取类的字节码

1.Class.forName();  静态方法		会导致类加载,静态代码执行
2.obj.getClass()		放回obj对象的类型
3.数据类型的class属性
4.newInstance()  创建对象

实列:

public static void main(String[] args){
        Class c1 = null;
        try {
            c1 = Class.forName("java.lang.String");  //D:\java\lib\rt.jar\java\lang\String
            System.out.println(c1);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        String s = "abc";
        Class c2 = s.getClass();
        Class c3 = String.class;
        System.out.println(c2 == c1);   //true
        System.out.println(c3 == c1);   //true
    }

结果为true的理解:
请添加图片描述
反编译用到的User类

public class User {
    public int no;
    private String name;
    protected int age;
    boolean sex;

    public boolean login(String name,String password){
        if ("admin".equals(name) && "123456".equals(password)) {
            return true;
        }
        return false;
    }

    public void logout(){
        System.out.println("系统已经安全退出!");
    }

    public User(int no, String name, int age, boolean sex) {
        this.no = no;
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "User{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", sex=" + sex +
                '}';
    }
}

2.Field

使用:

		 Class c = Class.forName("User");
        Field nameField = c.getDeclaredField("name");
        Object user = c.newInstance();
//        打破封装
        nameField.setAccessible(true);   //[əkˈsesəbl]   可见到的
        nameField.set(user,"jackson");
        System.out.println(nameField.get(user));

3.Method

		Class c = Class.forName("User");
        Object obj = c.newInstance();
        Method loginMethod = c.getDeclaredMethod("login",String.class,String.class);
        Object retValue = loginMethod.invoke(obj,"admin","123456");
        System.out.println(retValue);

4.Constructor

		Class c = Class.forName("User");
        Constructor constructor =  c.getDeclaredConstructor(int.class,String.class,int.class,boolean.class);
        Object obj = constructor.newInstance(100,"jackson",18,true);
        System.out.println(obj);

5.父类及接口

		Class c = Class.forName("java.lang.String");
        Class superClass = c.getSuperclass();
        System.out.println(superClass.getName());

        Class[] interfaces = c.getInterfaces();
        for(Class in : interfaces){
            System.out.println(in.getName());
        }

6.反编译

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class Test{
    public static void main(String[] args) throws Exception {
        int i = 0;
        StringBuilder s = new StringBuilder();
        Class c = Class.forName("java.lang.Integer");
        s.append(Modifier.toString(c.getModifiers()) + " class " + c.getSimpleName() + " extends ");
        s.append(c.getSuperclass().getSimpleName() + "\n");
        s.append("\timplements ");
        for(Class interf : c.getInterfaces()){
            s.append(interf.getSimpleName() + ",");
        }
        if(s.toString().endsWith(",")){
               s.deleteCharAt(s.length() - 1);
        }
        s.append("\n{\n");
        for(Field field : c.getDeclaredFields()){
            s.append("\t" + Modifier.toString(field.getModifiers()) + " "
                    + field.getType().getSimpleName() + " " + field.getName() + ";\n");
        }
        for(Method method: c.getDeclaredMethods()){
            s.append("\t"
                    + (Modifier.toString(method.getModifiers()) == "" ? "":Modifier.toString(method.getModifiers()) + " "));
            s.append(method.getReturnType().getSimpleName() + " ");
            s.append(method.getName() + "(");
            i = 0;
           for(Class parameterTyep : method.getParameterTypes()){
               s.append(parameterTyep.getSimpleName() + " par" + (i++) + ",");
           }
           if(s.toString().endsWith(",")){
               s.deleteCharAt(s.length() - 1);
           }
            s.append(") {};\n");
        }
        for(Constructor constructor : c.getDeclaredConstructors()){
            s.append("\t"
                    + (Modifier.toString(constructor.getModifiers())=="" ? "" : Modifier.toString(constructor.getModifiers()) + "\t" )
                    + c.getSimpleName() + "(");
            i = 0;
            for(Class parameterTyep : constructor.getParameterTypes()){
               s.append(parameterTyep.getSimpleName() + " par" + (i++)  + ",");
           }
           if(s.toString().endsWith(",")){
               s.deleteCharAt(s.length() - 1);
           }
            s.append(") {};\n");
        }
        s.append("}");
        System.out.println(s);
    }
}

二、注解Annotation

引用数据类型,编译后生成class文件
[修饰符列表] @interface 注解类型名{}		

1.元注解

用来标注注解类型的注解
@Target(ElementType.METHOD[元素类型])		标注注解出现的位置  
@Retention(RetentionPolicy.SOURCE[保存性策略])		被标注的注解保存在哪里

2.内置注解

@Override		只能注解方法(编译器检查是否时重写父类的方法)

源码:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
@Deprecated		标记已过时

过时,表现形式:有中划线
在这里插入图片描述
源码:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, MODULE, PARAMETER, TYPE})
public @interface Deprecated {
    String since() default "";
    boolean forRemoval() default false;    //Removal 移除
}

3.常用类型源码

ElementType源码:

enum ElementType {
    TYPE,
    FIELD,
    METHOD,
    PARAMETER,
    CONSTRUCTOR,
    LOCAL_VARIABLE,
    ANNOTATION_TYPE,
    PACKAGE,
    TYPE_PARAMETER,
    TYPE_USE,
    MODULE,
}

RetentionPolicy源码:

enum RetentionPolicy {
    SOURCE,
    CLASS,
    RUNTIME		//可以保留在class文件中,可以被反射机制锁读取
}

4.自定义注解

使用注解时,必须给注解属性赋值,除非赋有默认值  属性定义		String name() default "";
只有一个value()属性值,赋值时属性名可以省略
属性值类型:
	基本数据类型,String,Class,及它们的数组形式,给数组赋值使用大括号,只有一个元素时,可以省略大括号

5.反射注解

//Myannotion自定义注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Myannotation {

    String value() default "重庆";
}

//测试类
public class Test{
    public static void main(String[] args) throws Exception {
        Class c  = Class.forName("Test");
        if(c.isAnnotationPresent(Myannotation.class)){// 判断该类是否有该注解
            Myannotation myannotation = (Myannotation) c.getAnnotation(Myannotation.class);
            System.out.println(myannotation.value());       //获取注解属性值
        }
    }
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值