java反射机制

反射是java中的动态机制,它允许我们在程序运行期间再确定类的实例化,方法的调用,属性的调用等,而不是传统意义上的在编码期间确定。

因此,反射可以大大的提高代码的灵活度,但是随之而来的是更多的系统开销和较慢的运行速度,因此不能过度的依赖反射。

Class类

Class的每一个实例用于表示JVM加载的一个类,所以我们也称Class的实例

为类的类对象。

当JVM加载一个类时会同时实例化一个Class的实例与之对应,这个Class实例

中会保存该类的一切信息(类名,有哪些方法,构造器,属性,注解等等)

我们在程序运行期间通过某个类的类对象来操作这个类。因此使用反射操作某个

类的第一件事就是获取该类的类对象

获取一个类的类对象有三种方式:

  • 1:类名.class

    例如:

    Class cls = String.class;

    Class cls = int.class (基本类型只能通过这种方式获取类对象)

  • 2:Class.forName(String className)

    通过Class的静态方法forName,传入对应类的完全限定名(包名.类名)的

    形式获取类对象

    Class cls = Class.forName("java.lang.String");

  • 3:通过类加载器ClassLoader加载类对象

package reflect;

import java.lang.reflect.Method;

/**
* java反射机制
* 反射是java中的动态机制,它允许我们在程序运行期间再确定类的实例化,方法的调用,
* 属性的调用等,而不是传统意义上的在编码期间确定。
*
* 因此,反射可以大大的提高代码的灵活度,但是随之而来的是更多的系统开销和较慢的
* 运行速度,因此不能过度的依赖反射。
*/
public class ReflectDemo1 {
public static void main(String[] args) throws ClassNotFoundException {
/*
Class类
Class的每一个实例用于表示JVM加载的一个类,所以我们也称Class的实例
为类的类对象。
当JVM加载一个类时会同时实例化一个Class的实例与之对应,这个Class实例
中会保存该类的一切信息(类名,有哪些方法,构造器,属性,注解等等)
我们在程序运行期间通过某个类的类对象来操作这个类。因此使用反射操作某个
类的第一件事就是获取该类的类对象 获取一个类的类对象有三种方式:
1:类名.class
例如:
Class cls = String.class;
Class cls = int.class (基本类型只能通过这种方式获取类对象) 2:Class.forName(String className)
通过Class的静态方法forName,传入对应类的完全限定名(包名.类名)的
形式获取类对象
Class cls = Class.forName("java.lang.String"); 3:通过类加载器ClassLoader加载类对象 */ //获取String的类对象
// Class cls = String.class; /*
Class.forName()
该方法要求必须处理异常:ClassNotFoundException 当指定的字符串(对应类的完全限定名)有误时会抛出该异常,或指定的
路径下无法找到该类时也会抛出该异常(多发生于通过反射加载第三方
jar文件里的类,有时我们忘记将该jar导入环境变量中,导致JVM无法
通过正确的包路径找到它)。
*/
// Class cls = Class.forName("java.lang.String"); /*
类加载器ClassLoader
类加载器有很多中不同的实现,创建方式也各不相同。
最常用的是如下方式:
ClassLoader loader = 当前类.class.getClassLoader();
类加载器除了可以加载类对象,还可以做很多和环境变量相关的操作,功能多。
*/
ClassLoader classLoader = ReflectDemo1.class.getClassLoader();
Class cls = classLoader.loadClass("java.lang.String"); //查看类名
//获取类的完全限定名(包名.类名)
String className = cls.getName();
System.out.println("类名:"+className);
//仅获取类名
className = cls.getSimpleName();
System.out.println("类名:"+className); //通过类对象获取其表示的类的所有方法
//获取所有公开方法和从超类继承的方法
// Method[] methods = cls.getMethods();
// for(Method method : methods){
// System.out.println(method.getName());
// } //获取本类定义的方法(包含私有方法,但是不含有从超类继承的方法)
Method[] methods = cls.getDeclaredMethods();
for(Method method : methods){
System.out.println(method.getName());
}
}
}

使用反射机制进行对象的实例化

Class提供的方法:

Object newInstance()

该方法可以使用其表示的类的无参构造器进行对象实例化

package reflect;

/**
* 使用反射机制进行对象的实例化
*/
public class ReflectDemo2 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
Person p = new Person();//硬编码,编码期间确定实例化那个类
System.out.println(p); /*
使用反射机制实例化
1:获取要实例化类的类对象
2:通过类对象的newInstance方法实例化
*/
//1加载类对象
// Class cls = Class.forName("reflect.Person"); ClassLoader classLoader = ReflectDemo2.class.getClassLoader();
Class cls = classLoader.loadClass("reflect.Person"); //2通过类对象实例化
Object o = cls.newInstance();//调用无参构造器
System.out.println(o); }
}

使用有参构造器实例化对象

package reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; /**
* 使用有参构造器实例化对象
*/
public class ReflectDemo3 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Person p = new Person("刘苍松",55);
System.out.println(p); //加载类对象
Class cls = Class.forName("reflect.Person");
//获取无参构造器
// Constructor c = cls.getConstructor();
// Object o = c.newInstance(); //先获取指定的构造器:Person(String name,int age)
Constructor c = cls.getConstructor(String.class,int.class);
Object o = c.newInstance("刘苍松",55);
System.out.println(o);
}
}

使用反射机制调用方法

调用无参数方法:

package reflect;

import java.lang.reflect.Method;
import java.util.Scanner; /**
* 使用反射机制调用方法
*/
public class ReflectDemo4 {
public static void main(String[] args) throws Exception {
Person p = new Person();
p.sayHello(); Scanner scanner = new Scanner(System.in);
System.out.println("请输入类名:");
String className = scanner.nextLine();
System.out.println("请输入方法名:");
String methodName = scanner.nextLine(); //实例化
ClassLoader classLoader = ReflectDemo4.class.getClassLoader();
// Class cls = classLoader.loadClass("reflect.Person");
Class cls = classLoader.loadClass(className);
Object o = cls.newInstance();//new Person() //调用方法
//1通过类对象获取要调用的方法
// Method method = cls.getMethod("sayHello");//获取无参方法sayHello
Method method = cls.getMethod(methodName);
//2通过方法对象执行该方法
method.invoke(o);//o.sayHello() o实际上是一个Person对象
}
}

调用有参方法:

package reflect;

import java.lang.reflect.Method;

/**
* 调用有参方法
*/
public class ReflectDemo5 {
public static void main(String[] args) throws Exception {
Class cls = Class.forName("reflect.Person");
Object o = cls.newInstance(); //say(String info)
Method m = cls.getMethod("say",String.class);
m.invoke(o,"hello~~");//p.say("hello~~") //say(String info,int sum)
Method m2 = cls.getMethod("say",String.class,int.class);
m2.invoke(o,"嘿嘿",5); }
}

访问私有方法:

package reflect;

import java.lang.reflect.Method;

/**
* 使用反射机制调用私有方法
*/
public class ReflectDemo6 {
public static void main(String[] args) throws Exception {
Person p = new Person();
// p.hehe();//编译不通过! Class cls = Class.forName("reflect.Person");
Object o = cls.newInstance(); //获取私有方法:private void hehe()
// Method m = cls.getMethod("hehe");
//获取私有方法不能用getMethod,(这用来获取公开方法)
Method m = cls.getDeclaredMethod("hehe");
m.setAccessible(true);//强制访问
m.invoke(o);//o.hehe()
}
}

day11 Java反射机制的更多相关文章

  1. 第28章 java反射机制

    java反射机制 1.类加载机制 1.1.jvm和类 运行Java程序:java 带有main方法的类名 之后java会启动jvm,并加载字节码(字节码就是一个类在内存空间的状态) 当调用java命令 ...

  2. Java反射机制

    Java反射机制 一:什么事反射机制 简单地说,就是程序运行时能够通过反射的到类的所有信息,只需要获得类名,方法名,属性名. 二:为什么要用反射:     静态编译:在编译时确定类型,绑定对象,即通过 ...

  3. java基础知识(十一)java反射机制(上)

    java.lang.Class类详解 java Class类详解 一.class类 Class类是java语言定义的特定类的实现,在java中每个类都有一个相应的Class对象,以便java程序运行时 ...

  4. java基础知识(十一)java反射机制(下)

    1.什么是反射机制? java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象都能够调用他的属性和方法,这种动态获取属性和方法的功能称为java的反射机制. ...

  5. Java反射机制专题

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

  6. java反射机制深入详解

    java反射机制深入详解  转自:http://www.cnblogs.com/hxsyl/archive/2013/03/23/2977593.html 一.概念 反射就是把Java的各种成分映射成 ...

  7. Java反射机制DOME

    Java反射机制 public class TestHibernate { @Test public void TestHb(){ try { Class cs = Class.forName(&qu ...

  8. 反射——Java反射机制

    反射概述 什么是反射? ①   反射的概念是由Smith在1982年首次提出的,主要指程序可以访问.检测和修改它本身状态或行为的一种能力. ②   JAVA反射机制是在运行状态中,对应任意一个类,都能 ...

  9. Java反射机制可以动态修改实例中final修饰的成员变量吗?

    问题:Java反射机制可以动态修改实例中final修饰的成员变量吗? 回答是分两种情况的. 1. 当final修饰的成员变量在定义的时候就初始化了值,那么java反射机制就已经不能动态修改它的值了. ...

随机推荐

  1. 2003031121-浦娟-python数据分析五一假期作业

    项目 内容 课程班级博客链接 20级数据班(本) 这个作业要求链接 Python作业 博客名称 2003031121-浦娟-python数据分析五一假期作业 要求 每道题要有题目,代码(使用插入代码, ...

  2. 基本命令学习 -(4)链接文件:ln命令

    关注「开源Linux」,选择"设为星标" 回复「学习」,有我为您特别筛选的学习资料~ 前言 在Windows系统中,快捷方式是指向原始文件的一个链接文件,原文件一旦被删除或剪切到其 ...

  3. PCIe引脚PRSNT与热插拔

    热插拔的基本目的是要让PCIe设备按照规定的顺序.原则,从系统中移除或插入到系统中来,并能正常的工作,且不影响系统的正常运行.事实上,PCIe"热插拔"的关键目的就是为前面面所提到 ...

  4. nodejs + koa + typescript 集成和自动重启

    版本说明 Node.js: 16.13.1 全局安装 TypeScript yarn global add typescript 创建项目 创建如下目录结构 project ├── src │ └── ...

  5. Packed Ciphertexts in LWE-based Homomorphic Encryption:解读

    本节内容记录阅读该论文的笔记 介绍 首先,介绍了两种明文"打包"的方法:PVW和SV PVW:对应论文(PVW:A framework for efficient and comp ...

  6. Android 12(S) 图像显示系统 - GraphicBuffer同步机制 - Fence

    必读: Android 12(S) 图像显示系统 - 开篇 一.前言 前面的文章中讲解Android BufferQueue的机制时,有遇到过Fence,但没有具体讲解.这篇文章,就针对Fence这种 ...

  7. 101_Power Pivot DAX 累计至今,历史累计至今

    焦棚子的文章目录 一.背景 DAX中已经有诸如YTD,QTD,MTD时间智能函数.用起来也比较方便. 但很多时候需要看历史累计至今的数据,需要自己根据实际情况写dax. 今天抛砖引玉,写一个示例. 二 ...

  8. 上半年最中意的 GitHub 更新「GitHub 热点速览 v.22.21」

    2022 年的热点速览加入 GitHub 产品动态之后,这次的图片显示是最得我意的,因为可以提升图片查看人的看片体验.而 GitHub 社区方面,GitHub 官方发布了部分开源项目的新版本.与此同时 ...

  9. Fail2ban 命令详解 fail2ban-server

    Fail2ban的服务端操作命令,用于启动一个Fail2ban服务. root@local:~# fail2ban-server --help Usage: /usr/bin/fail2ban-ser ...

  10. Unity中通过深度优先算法和广度优先算法打印游戏物体名

    前言:又是一个月没写博客了,每次下班都懒得写,觉得浪费时间.... 深度优先搜索和广度优先搜索的定义,网络上已经说的很清楚了,我也是看了网上的才懂的,所以就不在这里赘述了.今天讲解的实例,主要是通过自 ...