Java学习笔记9-反射1

1、反射的理解

(1)**Reflection(反射)**是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。
(2)框架 = 反射 + 注解 + 设计模式

2、java.lang.Class类

  1. 类的加载过程:
  • 程序经过javac.exe命令以后,会生成一个或多个字节码文件(.class结尾)
  • 接着我们使用java.exe命令对某个字节码文件进行解释运行。相当于将某个字节码文件加载到内存中。此过程就称为类的加载,加载到内存中的类,我们就称为运行时类,就作为Class的一个实例。
  1. Class的实例就对应着一个运行时类
  2. 加载到内存中的运行时类,会缓存一定的时间。在此时间之内,我们可以通过不同的方式来获取此运行时类
package com.such.mytest;

import java.io.UnsupportedEncodingException;
import java.util.Scanner;
import java.util.Arrays;

public class Test {
    public static void main(String[] args) throws Exception {
    
        //方式一:调用运行时类的属性:.class
        Class clazz1 = MyPerson.class;
        System.out.println("clazz1: " + clazz1);
        
        //方式二:通过运行时类的对象,调用getClass()
        MyPerson p1 = new MyPerson();
        Class clazz2 = p1.getClass();
        System.out.println("clazz2: " + clazz2);

        //方式三:调用Class的静态方法:forName(String classPath)
        Class clazz3 = Class.forName("com.such.mytest.MyPerson");
        System.out.println("clazz3: " + clazz3);

        System.out.println(clazz1 == clazz2);
        System.out.println(clazz1 == clazz3);

        //方式四:使用类的加载器:ClassLoader 
        ClassLoader classLoader = Test.class.getClassLoader();
        Class clazz4 = classLoader.loadClass("com.such.mytest.MyPerson");
        System.out.println("clazz4: " + clazz4);

        System.out.println(clazz1 == clazz4);
}

class MyPerson {
    private String name;
    public int age;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public MyPerson(String name, int age) {

        this.name = name;
        this.age = age;
    }

    private MyPerson(String name) {
        this.name = name;
    }

    public MyPerson() {
        System.out.println("Person()");
    }

    public void show(){
        System.out.println("你好,我是一个人");
    }

    private String showNation(String nation){
        System.out.println("我的国籍是:" + nation);
        return nation;
    }
}

在这里插入图片描述

3、newInstance() 创建对应的运行时类的对象

newInstance():调用此方法,创建对应的运行时类的对象。内部调用了运行时类的空参的构造器。

要想此方法正常的创建运行时类的对象,要求:

  1. 运行时类必须提供空参的构造器
  2. 空参的构造器的访问权限得够。通常,设置为public。

java bean中要求提供一个public的空参构造器。原因:

  1. 便于通过反射,创建运行时类的对象
  2. 便于子类继承此运行时类时,默认调用super()时,保证父类有此构造器
public void test1() throws Exception {
    Class<MyPerson> clazz = MyPerson.class;
    MyPerson obj = clazz.newInstance();
    System.out.println(obj);
}

在这里插入图片描述

4、创建类

import java.io.Serializable;

public class Creature<T> implements Serializable {
    private char gender;
    public double weight;

    private void breath(){
        System.out.println("生物呼吸");
    }

    public void eat(){
        System.out.println("生物吃东西");
    }
}
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*;

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String value() default "hello";
}
public interface MyInterface {
    void info();
}
@MyAnnotation(value="hi")
public class Person extends Creature<String> implements Comparable<String>,MyInterface{

    private String name;
    int age;
    public int id;

    public Person(){}

    @MyAnnotation(value="abc")
    private Person(String name){
        this.name = name;
    }

    Person(String name,int age){
        this.name = name;
        this.age = age;
    }
    @MyAnnotation
    private String show(String nation){
        System.out.println("我的国籍是:" + nation);
        return nation;
    }

    public String display(String interests,int age) throws NullPointerException,ClassCastException{
        return interests + age;
    }


    @Override
    public void info() {
        System.out.println("我是一个人");
    }

    @Override
    public int compareTo(String o) {
        return 0;
    }

    private static void showDesc(){
        System.out.println("我是一个可爱的人");
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", id=" + id +
                '}';
    }
}

5、获取当前运行时类的属性结构

  1. getFields():获取当前运行时类及其父类中声明为public访问权限的属性
  2. getDeclaredFields():获取当前运行时类中声明的所有属性。(不包含父类中声明的属性)
public void test1(){

    Class clazz = Person.class;

    //获取属性结构
    //getFields():获取当前运行时类及其父类中声明为public访问权限的属性
    Field[] fields = clazz.getFields();
    for(Field f : fields){
        System.out.println(f);
    }
    System.out.println();

    //getDeclaredFields():获取当前运行时类中声明的所有属性。(不包含父类中声明的属性)
    Field[] declaredFields = clazz.getDeclaredFields();
    for(Field f : declaredFields){
        System.out.println(f);
    }
}

在这里插入图片描述

 @Test
 public void test2(){
     Class clazz = Person.class;
     Field[] declaredFields = clazz.getDeclaredFields();
     for(Field f : declaredFields){
         //1.权限修饰符
         int modifier = f.getModifiers();
         System.out.println(Modifier.toString(modifier));

         //2.数据类型
         Class type = f.getType();
         System.out.print(type.getName() + "\t");

         //3.变量名
         String fName = f.getName();
         System.out.print(fName);

         System.out.println();
     }
 }

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值