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. js console.log打印变量注意事项

    如果是基本类型变量是没有异常的 let str = 'string' console.log(str) // string str = '改变了str变量' 如果是引用类型,打印就要注意了 let o ...

  2. java基础4.18

    1.java的"一次编写,处处运行"如何实现?: 答:java之所有能实现一次编译,到处运行,是因为java在每个系统平台上都有java虚拟机(jvm),java编译的中间文件cl ...

  3. 如何在Linux上恢复误删除的文件或目录

    Linux不像windows有那么显眼的回收站,不是简单的还原就可以了.linux删除文件还原可以分为两种情况,一种是删除以后在进程存在删除信息,一种是删除以后进程都找不到,只有借助于工具还原,这里分 ...

  4. ThinkPHP V6.0.12在php8.1下验证码出现问题

    一.问题描述 1.项目需求要求使用PHP8.1.*版本 2.运行程序发现验证码不生效报错如下: 二.错误描述 1.报错信息得出:从浮点(数字)到整数的隐式转换将失去精度 三.解决流程 1.找到报错文件 ...

  5. 1903021121-刘明伟 实验一 19信计JAVA—Markdown排版学习

    项目 内容 班级博客链接 19信计班(本) 作业要求链接 实验一 课程学习目标 学习使用Markdown排版 这个作业帮助我们实现了什么学习目标 学会使用Markdown排版 任务一:在博客园平台注册 ...

  6. 渗透:winpcap

    winpcap(windows packet capture)是windows平台下一个免费,公共的网络访问系统.开发winpcap这个项目的目的在于为win32应用程序提供访问网络底层的能力.它提供 ...

  7. 124_Power Pivot&Power BI DAX优化计算最大连续次数

    博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 一.背景 最大连续次数或者是最大连续子序列问题,在DAX中如何快速计算呢? 思路 1.N-1:按照INDEX错位 2.ST ...

  8. C++调用C#的动态库dll

    以往我们经常是需要使用C#来调用C++的dll,这通过PInvoke就能实现.现在在实际的项目过程中,有时会遇到在C++的项目中调用某个C#的dll来完成特定的某个功能,我们都知道,Native C+ ...

  9. 字节开源RPC框架Kitex的日志库klog源码解读

    前言 这篇文章将着重于分析字节跳动开源的RPC框架Kitex的日志库klog的源码,通过对比Go原生日志库log的实现,探究其作出的改进. 为了平滑学习曲线,我写下了这篇分析Go原生log库的文章,希 ...

  10. 渗透测试之sql注入验证安全与攻击性能

    由于渗透测试牵涉到安全性以及攻击性,为了便于交流分享,本人这里不进行具体网址的透露了. 我们可以在网上查找一些公司官方网站如(http://www.XXXXXX.com/xxxx?id=1) 1.拿到 ...