zoukankan      html  css  js  c++  java
  • JAVA基础-反射

    反射的基本概念

    Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法

    Java反射机制提供的功能

    • 在运行时判断任意一个对象所属的类

    • 在运行时构造任意一个类的对象

    • 在运行时判断任意一个类所具有的成员变量和方法

    • 在运行时调用任意一个对象的成员变量和方法

    • 生成动态代理

    反射相关的主要API

    • java.lang.Class: 代表一个类

    • java.lang.reflect.Method: 代表类的方法

    • java.lang.reflect.Field: 代表类的成员变量

    • java.lang.reflect.Constructor: 代表类的构造方法

    常用的反射方法

    • 前提:若已知具体的类,通过类的class属性获取,该方法
      最为安全可靠,程序性能最高
      实例:Class clazz = String.class;
    • 前提:已知某个类的实例,调用该实例的getClass()方法获
      取Class对象
      实例:Class clazz = “www.kkb.com”.getClass();
    • 前提:已知一个类的全类名,且该类在类路径下,可通过
      Class类的静态方法forName()获取,可能抛出ClassNotFoundException
      实例:Class clazz = Class.forName(“java.lang.String”);

    类的加载过程

    当程序主动使用某个类时,如果该类还未被加载到内存中,则系统会通过如下三个步骤来对该类进行初始化。

    了解ClassLoader

    类加载器是用来把类(class)装载进内存的。JVM 规范定义了两种类型的类加载器:启动类加载器(bootstrap)和用户自定 义加载器(user-defined class loader)。 JVM在运行时会产生 3个类加载器组成的初始化加载器层次结构 ,如下图所示

    反射的使用

    通过Class类来实现:

    package day18;
    
    import static org.junit.Assert.*;
    
    import org.junit.Test;
    
    public class PersonTest {
    
    	//没有反射概念之前我们如何使用对象
    	@Test
    	public void test01() throws Exception {
    		Person person = new Person();
    		person.name = "zhangsan";
    		person.age = 18;
    		person.show();
    		
    		System.out.println(person);
    	}
    	
    	//通过反射,得到我们Person对象
    	@Test
    	public void test02() throws Exception {
    		Class c = Person.class;
    		Person person = (Person)c.newInstance();
    		person.show();
    		System.out.println(person);
    	}
    	@Test
    	public void test03() throws Exception {
    		//第一种
    		Class c1 = String.class;
    		System.out.println(c1.getName());
    		Class P1 = Person.class;
    		System.out.println(P1.getName());
    		//第二种
    		Class class1 = "c".getClass();
    		System.out.println(class1.getName());
    		//第三种
    		Class class2 = Class.forName("day18.Person");	
    		System.out.println(class2.getName());
    		
    	}
    }
    /**
    java.lang.String
    day18.Person
    java.lang.String
    day18.Person
    
    */
    

    难道没有无参的构造器就不能创建对象了吗?

    不是!只要在操作的时候明确的调用类中的构造方法,并将参数传递进去

    之后,才可以实例化操作。步骤如下:

    1)通过Class类的getDeclaredConstructor(Class … parameterTypes) 取得本类的指定形参类型的构造器

    2)向构造器的形参中传递一个对象数组进去,里面包含了构造器中所需的各个参数。

    3)通过Constructor实例化对象。

    下面我们来举一个例子:

    我们的Person类构造如下:

    package day18;
    
    public class Person {
    	public String name;
    	public int age;
    	
    	public Person() {
    	}
        
    	public Person(int age,String name) {
    		this.name = name;
    		this.age = age;
    	}
    	
    	@Override
    	public String toString() {
    		return "Person [name=" + name + ", age=" + age + "]";
    	}
    
    	public void show() {
    		System.out.println(name +","+ age  );
    	}
    }
    
    

    随后我们通过反射的方式,来通过有参构造和无参构造来实现实例化:

    	@Test
    	public void test04() throws Exception {
    		//第一种必须有参数,并且注意构造器权限
    		Class class1 = Person.class;
    		Person person = (Person)class1.newInstance();
    	}
    	
    	@Test
    	public void test05() throws Exception {
            //方法二,使用其他构造方法
    		Class class1 = Person.class;
    		Constructor c1 = class1.getDeclaredConstructor( int.class  , String.class );
    		Person person = (Person)c1.newInstance(18,"Jeason");
    		System.out.println(person);
    	}
    
    
    /*
    Person [name=Jeason, age=18]
    */
    
  • 相关阅读:
    27. Remove Element
    列表变成字典
    1. Two Sum
    CVPR2019:What and How Well You Performed? A Multitask Learning Approach to Action Quality Assessment
    959. Regions Cut By Slashes
    118. Pascal's Triangle
    loj3117 IOI2017 接线 wiring 题解
    题解 NOI2019 序列
    题解 省选联考2020 组合数问题
    题解 Educational Codeforces Round 90 (Rated for Div. 2) (CF1373)
  • 原文地址:https://www.cnblogs.com/JeasonIsCoding/p/13232578.html
Copyright © 2011-2022 走看看