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. 【图解】面试题:ConcurrentHashMap是如何保证线程安全的

    注意:JDK1.7与JDK1.8中的ConcurrentHashMap主要延续HashMap的设计与思想,是在其基础上进行的相应优化 1.JDK1.7中的底层实现原理 (1)JDK1.7Concurr ...

  2. 评价管理后台PC端

    1.css动画效果    --2020.12.26 2.remove() --2020.12.28 3.执行顺序 --2020.12.30 4.联动 --2021.01.06 5.奥利给~ --202 ...

  3. 爬取百度页面代码写入到文件+web请求过程解析

    一.爬取百度页面代码写入到文件 代码示例: from urllib.request import urlopen #导入urlopen包 url="http://www.baidu.com& ...

  4. Css实例之信息提交

    代码实例: <!DOCTYPE html><html><head><meta charset="UTF-8"><title&g ...

  5. 每天一个 HTTP 状态码 101

    101 Switching Protocols 当客户端的请求具有 Upgrade HTTP 首部,表示要求服务器切换到指定协议:此时服务器端就可以向客户端响应 101 Switching Proto ...

  6. MVC - forward 和 redirect 的区别

    MVC - forward 和 redirect 的区别 forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器,浏览器根本不知道服 ...

  7. 腾讯云Redis全面升级,性能提升400%,可用性高达5个9

    2022年6月,腾讯云Redis全新升级,发布高性能版本,单节点可提供50W+吞吐,性能是原生Redis的4倍.同时,腾讯云Redis推出全球复制功能,解决原生Redis诸多痛点问题,可用性升级高达9 ...

  8. RMQ——ST表

    ST表 ST表是一种解决RMQ问题的强有力工具, 可以做到O(nlogn)预处理,O(1)查询. st[i][j] 表示区间 [i, i + 2 ^ j - 1] 的最大值. 初值 st[i][0] ...

  9. 慢到不能忍?别忍了,Ubuntu 21.10 APT 源修改为华为云镜像源

    更新记录 2022年4月15日:本文迁移自Panda666原博客,原发布时间:2021年3月29日. 2022年4月15日:将源改为华为云,华为云更方便.Ubuntu从20.04更新到21.10. 切 ...

  10. 17.Nginx 重写(location rewrite)

    Nginx 重写(location / rewrite) 目录 Nginx 重写(location / rewrite) 常见的nginx正则表达式 location lication的分类 loca ...