java基础-day18-注解. 反射

注解

注解标志: @ 如 @Override。分为JDK注解,元注解,自定义注解

JDK注解
@Override`                       重写方法
@Deprecated                      已过时
@SuppressWarnings("deprecation") 忽略警告 
@SafeVarargs                     jdk 1.7出现,堆污染,不常用 
@FunctionallInterface            jdk1.8出现,配合函数式编程拉姆达表达式,不常用
元注解

描述注解的注解。

@Target     表明注解的位置:类上、方法上、属性上
@Retention  注解的生命周期:源文件中、class文件中、运行时
@Inherited  允许子注解继承
@Documented 生成javadoc时会包含注解,不常用
@Repeatable 注解为可重复类型注解,可在同一个地方多次使用,不常用
@Target ElementType.class

描述注解的使用范围:

ElementType.ANNOTATION_TYPE    应用于注释类型
ElementType.CONSTRUCTOR        应用于构造函数
ElementType.FIELD              应用于字段或属性
ElementType.LOCAL_VARIABLE     应用于局部变量
ElementType.METHOD             应用于方法
ElementType.PACKAGE            应用于包声明
ElementType.PARAMETER          应用于方法的参数
ElementType.TYPE               应用于类的元素
@Retention RetentionPlicy.class

定义了注解的生命周期 SOURCE CLASS RUNTIME RetentionPlicy 类中

自定义注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public class Test1_Annotation {
    public static void main(String[] args) {
    }
}
//1,创建自定义注解Test:语法:@interface 注解名
//2、@Target指定注解的位置--ElementType.TYPE是指可以出现在类上
//3、@Retention指定注解的生命周期--RetentionPolicy.SOURCE是指在源码中有效
//@Target(  ElementType.METHOD )
@Target(  { ElementType.TYPE   , ElementType.METHOD    }  )
@Retention(RetentionPolicy.SOURCE)
@interface Test {
    //5、给注解添加属性--注解的语法和java略有不同
    String name()  default "" ;
    String value() default "" ;//8、特殊属性,赋值时可以简写
}
//4、使用自定义的注解Test
//6、使用Test注解时,同时给name属性赋值(没有默认值时)
//@Test(name="hello")
//7、如果name属性有了默认值,我们使用就可以省略赋值
//@Test(value="hello")
@Test("hello") //8.1、如果给value属性赋值,可以简写
class Hello {
    // @Test  The annotation @Test is disallowed for this location
    String name ;
    @Test
    public void method() {
        System.out.println(123);
    }
}

反射

Reflection 可在运行时获取一个类的所有信息,可以获取到任何定义的信息(包括成员变量、成员方法、构造器等),并且可以操纵类的字段、方法、构造器等部分

反射 class 类对象
Class.forName("类的全路径");
类名.class
对象.getclass();

常用方法:
获取包名、类名

clazz.getPackage().getName()  //包名
clazz.getSimpleName()         //类名
clazz.getName()              //完整类名

构造方法定义信息

getConstructor(参数类型列表)  //获得公开的构造方法
getConstructors()            //获得所有公开的构造方法
getDeclaredConstructors()    //获得所有的构造方法,包括私有

方法定义信息

getMethods()                //获得所有可见的方法,包括继承的
getMethod(方法名,参数类型列表)
getDeclareMethods()  //获得本类定义的方法,包括私有,不包括继承

反射新建实例

c.newInstance();  // 执行无参构造
c.newInstance(6,"abc"); //执行有参构造

反射调用成员方法

Method m = c.getDeclareMethod(方法名,参数类型列表)
m.setAccessible(true);   //使私有方法允许被调用
m.invoke(实例,参数数据)//让指定的实例来执行该方法
import org.junit.Test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
//这个类用来测试  反射获取学生类里的所有数据
//Junit单元测试方法: @Test   + void  + 没有参数
//运行:必须选中方法名,右键,run  as  , junit test...
public class Test3_Reflection2 {
    //利用反射创建对象
    @Test
    public void showObject() throws Exception {
        //1、获取Class对象
        Class<?> clazz = Student.class;
        //2、利用反射,创建对象
        Object obj = clazz.newInstance();//触发了无参构造
        //cn.tedu.reflection.Student@443b7951
        System.out.println(obj);
        //怎么触发含参构造
        //指定你想要触发 哪个 含参构造   
        //    clazz.getConstructor(String.class);//触发string类型的含参构造
        //    clazz.getConstructor(int.class);//触发int类型的含参构造
        Constructor c = clazz.getConstructor(String.class , int.class);
        Object obj2 = c.newInstance("皮皮霞",20);//给构造方法传参
        //cn.tedu.reflection.Student@14514713
        //Student [name=皮皮霞, age=20]
        System.out.println(obj2);
    }
    //获取学生类中的成员变量们
    @Test
    public void showFields() {
        //1、获取Class对象
        Class<?> clazz = Student.class;
        //2、获取所有   公共的   的属性们  
        Field[] fs = clazz.getFields() ;
        //3、遍历数组
        for (Field f : fs) {
            //4、获取变量名
            String name = f.getName() ;
            System.out.println(name);
            //5、获取变量的类型
            String type = f.getType().getName();
            System.out.println(type);
        }
    }
    //获取学生类中的构造方法们
    @Test
    public void showConstructor() {
        // 1、获取Class对象
        Class<?> clazz = Student.class;
        // 2、调用方法
        Constructor<?>[] cs = clazz.getConstructors() ;
        //3、遍历数组
        for(Constructor c : cs) {
            //4、获取方法名
            String name = c.getName();
            System.out.println(name);
            //5、获取参数的类型
            Class[] cls = c.getParameterTypes() ;
            System.out.println( Arrays.toString(cls)  );
        }
    }
    // 获取学生类中的成员方法们
    @Test
    public void showMethod() {
        // 1、获取Class对象
        Class<?> clazz = Student.class;
        // 2、调用方法
        Method[] ms = clazz.getMethods();
        // 3、遍历数组
        for (Method m : ms) {
            // 4、获取方法名
            String name = m.getName();
            System.out.println(name);
            //5、获取方法有没有参数
            Class<?>[] cls = m.getParameterTypes();
            System.out.println(  Arrays.toString(cls)  );
        }
    }
    @Test
    public void showClass() throws ClassNotFoundException {
        // 反射Class对象
        Class<?> clazz = Class.forName("cn.tedu.reflection.Student");
        Class<?> clazz2 = Student.class;
        Student s = new Student();
        Class<?> clazz3 = s.getClass();
        System.out.println(clazz);
        System.out.println(clazz2);
        System.out.println(clazz3);
    }
}
public class Student {
    public String name;
    public int age;
    public Student(){}
    public Student(String name,int age){
        this.name = name;
        this.age  = age;
    }
    public void save(){
        System.out.println("save()...");
    }
    public void show(int num){
        System.out.println("show()..."+num);
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

暴力反射

import org.junit.Test;
import java.lang.reflect.Method;
import java.util.Arrays;
//这个类用来 测试暴力反射Person 
public class Test4_ReflectPrivate {
    //暴力反射成员方法
    @Test
    public void showMethod() throws Exception {
        //1、获取Class对象
        Class clazz = Class.forName("cn.tedu.reflection.Person");
        //2、获取所有的方法们
        //    clazz.getMethods();  //反射  公共的  资源
        //3、暴力反射  --  所有   方法们  ---  getDeclaredMethods()--可以获取公共的或者私有的方法
        Method[] ms = clazz.getDeclaredMethods();
        for (Method m : ms) {
            String name = m.getName();
            System.out.println(name);
            Class<?>[] cls = m.getParameterTypes();
            System.out.println(  Arrays.toString(cls) );
        }
        //4、暴力反射    --   获取    单个   方法
        //getDeclaredMethod(m,n)-m是想要执行的方法名 -n是方法需要的参数类型
        Method method = clazz.getDeclaredMethod("show", null);
        //5、如何执行
        //--invoke(m,n)-m是想让哪个对象执行方法-n是方法需要的参数
        //!!设置私有可见
        method.setAccessible(true);
        Object obj = clazz.newInstance() ;
        method.invoke(obj, null) ;
    }
}
public class Person {
    private String name = "张三";
    private int age = 20;
    private void show(){
        System.out.println("show()...");
    }
    private void test(int a){
        System.out.println("test()..."+a);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值