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]
    */
    
  • 相关阅读:
    遗传算法的理解
    使用Grub Rescue 修复MBR
    java 虚拟机与并发处理几个问题简要(二)
    java 虚拟机与并发处理几个问题简要(一)
    Fence Repair POJ
    Best Cow Line---POJ 3617(贪心)
    迷宫的最短路径
    最大子段和
    Lake Counting --POJ 2386
    Ants POJ
  • 原文地址:https://www.cnblogs.com/JeasonIsCoding/p/13232578.html
Copyright © 2011-2022 走看看