zoukankan      html  css  js  c++  java
  • 类的反射_reflex

    JAVA反射机制

    JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
    JAVA反射(放射)机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。
     

    功能

    Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
     
    代码演示

    package com.svse.reflex;

    import java.io.IOException;
    import java.io.InputStream;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.util.Properties;
    import org.junit.Test;
    /***
    * 类的反射
    * @author Administrator
    * java反射机制提供的功能
    * 在运行时:
    * <1>判断任意一个对象所属的类
    * <2>构造任意一个类的对象
    * <3>判断任意一个类所具有的成员变量和方法
    * <4>调用任意一个对象的成员变量和方法
    * <5>生成动态代理
    */
    public class ClassReflex {

    //关于类的加载器classLoader
    @Test
    public void test5() throws ClassNotFoundException, IOException{
    ClassLoader classLoader=ClassLoader.getSystemClassLoader();
    System.out.println(classLoader);

    ClassLoader classLoader1=classLoader.getParent();
    System.out.println(classLoader1);

    ClassLoader classLoader2=classLoader1.getParent();
    System.out.println(classLoader2);

    Class clazz=Person.class;
    ClassLoader classLoader3=clazz.getClassLoader();
    System.out.println(classLoader3);

    String forName="java.lang.String";
    Class clazz2=Class.forName(forName);
    ClassLoader classLoader4=clazz2.getClassLoader();
    System.out.println(classLoader4);

    ClassLoader classLoader5=this.getClass().getClassLoader();
    InputStream is=classLoader5.getResourceAsStream("com\svse\reflex\db.properties");//读取properties文件信息
    Properties properties=new Properties();
    properties.load(is);
    String name=properties.getProperty("name");
    String password=properties.getProperty("password");
    System.out.println(name+" : "+password);

    }

    /***
    * 获取class实例的三种方式
    * @throws ClassNotFoundException
    */
    @Test
    public void test4() throws ClassNotFoundException{
    //1:调用运行时类本身的class属性
    Class clazz=Person.class;
    System.out.println(clazz.getName());
    Class clazz2=String.class;
    System.out.println(clazz2.getName());
    //2:通过运行时类的对象获取
    Person p=new Person();
    Class clazz3=p.getClass();
    System.out.println(clazz3.getName());
    //3:通过class的静态方法获取 (体会一下反射的动态性)
    String forName="com.svse.reflex.Person";
    Class clazz4=Class.forName(forName);
    System.out.println(clazz.getName());

    //4:了解类的加载器classLoader
    ClassLoader classLoader=this.getClass().getClassLoader();
    Class clazz5=classLoader.loadClass(forName);
    System.out.println(clazz5.getName());

    System.out.println(clazz==clazz2);
    System.out.println(clazz==clazz3);
    System.out.println(clazz==clazz4);
    System.out.println(clazz==clazz5);

    }


    /**
    * java.lang.Class 是反射的源头
    * 通过运行时类的getClass()方法创建实例
    */
    @Test
    public void test3(){
    Person p=new Person();
    Class clazz=p.getClass();//通过运行时类的对象,调用其getClass()方法,返回其运行时类
    System.out.println(clazz);
    }



    //有了反射之后,可以通过反射创建一个类的对象,并调用其中的属性和方法
    @Test
    public void test2() throws Exception{
    Class clazz=Person.class;
    //1创建clazz对应的运行时类person的对象
    Person p=(Person) clazz.newInstance();
    System.out.println(p);

    //2 通过反射调用类的属性
    Field f1=clazz.getField("name");
    f1.set(p, "王小米");
    System.out.println(p);
    //Field f2=clazz.getField("age");
    Field f2=clazz.getDeclaredField("age");//如果属性设置为private
    f2.setAccessible(true);//必须设置允许访问为true,否则就获取不到私有属性的值
    f2.set(p, 26);
    System.out.println(p);
    //3 通过反射调用类的方法
    Method m1=clazz.getMethod("show");
    m1.invoke(p);
    Method m2=clazz.getMethod("display",String.class);
    m2.invoke(p,"china");
    //4

    }

    //在有反射前,传统的方法,如何创建一个类的对象,并调用其中的属性和方法
    @Test
    public void test1(){
    Person p=new Person();
    p.setAge(25);
    p.setName("张三");
    System.out.println(p);
    p.show();
    p.display("china");
    }

    }

    db.properties文件

    name=zhangsan
    password=123456

    Person.java文件

    package com.svse.reflex;

    public class Person {

    public String name;
    private int age;

    public Person() {
    super();
    }

    public Person(String name) {
    super();
    this.name = name;
    }

    public Person(String name, int age) {
    super();
    this.name = name;
    this.age = age;
    }

    public void add(String name){
    System.out.println("公有的---"+name);
    }

    private void find(String name){
    System.out.println("私有的---"+name);
    }

    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 void show(){
    System.out.println("我是一个man");
    }
    public void display(String nation){
    System.out.println("我的国籍是:"+nation);
    }

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

    }

  • 相关阅读:
    无法为数据库 'tempdb' 中的对象分配空间,因为 'PRIMARY' 文件组已满
    数据库通用分页存储过程
    ef linq 中判断实体中是否包含某集合
    linq 动态判断
    bootstrap切换按钮点击后显示的颜色
    abp vue vscode 配置
    abp ef codefirst Value cannot be null. Parameter name: connectionString
    git diff 分支1 分支2 --stat命令没有将所有的不同显示出来
    区块链相关介绍
    需求分析工作流程
  • 原文地址:https://www.cnblogs.com/zhaosq/p/9811879.html
Copyright © 2011-2022 走看看