13
2019
03

JAVA学习-Java高级-Java反射机制

Java高级-Java反射机制

1.反射概述

什么是反射?

反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。

Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象方法的功能称为Java语言的反射机制。

简单来说,反射机制指的是程序在运行时能够获取自身和信息。在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息,包括访问修饰符、父类、实现的接口、属性和方法的所有信息,并可在运行时创建对象、修改属性(包括私有的)、调用方法(包括私有的)。

2.反射机制

动态编译:运行时确定类型,绑定对象、动态编译最大限度发挥了java的灵活性,体现了多态的应用,用以降低类之间的耦合性。

反射的缺点:对性能有一点影响。使用反射是一种解释操作,这类操作总是慢于直接执行的相同操作。

3.Class对象:

Class对象是Reflection故事起源。要想操纵类中的属性和方法,都必须从获取Class对象开始

Class类没有公共的构造方法,Class对象是在加载类时,由Java虚拟机以及通过调用类加载器中的方法自动构造的,因此不能显式地声明一个Class对象。

Class对象的获取方式:

object.getClass():对象的getClass方法获取

class.getSuperclass():获取当前class的父类class

.class属性:通过类名.class属性,获取类的class

Class.forName(类名):通过传入的字符串格式的类名获取class

.TYPE:基本数据类型包装类的TYPE属性获取class


Demo:

package pkg1.classtype;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ClassDemo {
public static void main(String[] args) throws Exception {
test1();
test2();
test3();
}
public static void test1(){
Employee employee=new Employee("zs", 22);
//获取Class对象
Class<?> class1 = employee.getClass();
//class1 = Employee.class;
//try {
//class1 = Class.forName("pkg1.classtype.Employee");
//} catch (ClassNotFoundException e) {
//// TODO Auto-generated catch block
//e.printStackTrace();
//}
System.out.println("普通类 类名:"+class1.getName());
System.out.println("父类名:"+class1.getSuperclass().getName());
//获取基础数据类型的Class对象
Class<?> class2 = int.class;
//class2 = Integer.TYPE;//获取包装类对应的基础数据类型class
System.out.println("基础数据类型 类名:"+class2.getName());
//基本数据类型Class没有父类
System.out.println("父类:"+class2.getSuperclass());
//包装类的Class对象
Class<?> class3 = Integer.class;
System.out.println("基础数据包装类 类名:"+class3.getName());
//基本数据类型Class没有父类
System.out.println("父类名:"+class3.getSuperclass().getName());
System.out.println("——————————————————————————————————————————");
}
public static void test2() throws Exception{
//获取类关联的Class对象
Class<?> class1 = Class.forName("pkg1.classtype.Employee");
//通过反射构造实例
//Employee employee = (Employee)class1.newInstance();//无参构造方法,相当于 .getConstructor(new Class[]{}).newInstance(new Class[]{})
//带参数的构造函数,传入参数类型Class列表,参数值列表
Employee employee = (Employee)class1.getConstructor(new Class[]{String.class,int.class}).newInstance(new Object[]{"zhangsan",24});
System.out.println(employee);
//获取Class对象的指定公共方法
Method methodToString = class1.getDeclaredMethod("toString", new Class[]{});
System.out.println(methodToString.getName());
 String desc = (String)methodToString.invoke(employee, new Object[]{});
 System.out.println("invoke result:"+desc);
//获取Class对象的私有方法
Method methodWork = class1.getDeclaredMethod("work", new Class[]{});
System.out.println(methodWork.getName());
methodWork.setAccessible(true);//设置私有方法可被访问
methodWork.invoke(employee, new Object[]{});//调用私有方法,但不建议这么做
 //获取Class对象的所有方法
 //method.getModifiers()为访问修饰符,1为Public,2为private,4为protected
 Method []methods = class1.getDeclaredMethods();
 for(Method method:methods){
 System.out.println(method.getName()+" "+method.getModifiers()+" "+method.getReturnType());
 }
 Field fieldName = class1.getDeclaredField("name");
 fieldName.setAccessible(true);//设置属性可访问
 fieldName.set(employee,"li si");//修改属性值
 System.out.println(fieldName.get(employee));//输出属性值
 System.out.println("——————————————————————————————————————————");
}
//使用反射来创建数组
public static void test3() throws Exception{
//创建一维数组
Class<?> classStr = Class.forName("java.lang.String");
Object array = Array.newInstance(classStr, 5);
Array.set(array, 0, "hello");//在数组下标0位置赋值
System.out.println(Array.get(array,0));//取数组下标0位置的值
//创建二维数组
int [] dimens = {3,3};
Object array2 = Array.newInstance(int.class,dimens);//二维数组
Object array2_3 = Array.get(array2,2);//获取第三行,是一个一维数组
Array.setInt(array2_3,2,100);//给第三行第三列赋值
int [][]arr = (int[][])array2;
System.out.println(arr[2][2]);
System.out.println("——————————————————————————————————————————");
}
}
class Employee{
public Employee() {
super();
}
public Employee(String name, int age) {
super();
this.name = name;
this.age = age;
}
private String 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;
}
private int age;
@Override
public String toString() {
return "Employee [name=" + name + ", age=" + age + "]";
}
private void work(){
System.out.println("I am working");
}
}

效果:



版权声明:
作者:真爱无限 出处:http://www.pukuimin.top 本文为博主原创文章版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接.
« 上一篇下一篇 »

相关文章:

评论列表:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。