目录

  • 1.反射机制概述
  • 2.获取class的三种方式
    • 2.1.Class.forName()方式
    • 2.2.obj.getClass()方式
    • 2.3..class方式
  • 3.通过反射实例化对象
  • 4.通过读属性文件实例化对象
  • 5.只让静态代码快执行可以使用forName
  • 6.以流的形式直接返回
  • 7.资源绑定器
  • 8.类加载器
  • 9.双亲委派机制
  • 10.总结

1.反射机制概述

反射机制有什么用
通过java语言中的反射机制可以操作字节码文件。
优点类似于黑客。(可以读和修改字节码文件。)
通过反射机制可以操作代码片段。(class文件。)
反射机制的相关类在哪个包下?
java.lang.reflect.*;
java.lang.Class; //代表字节码文件,代表一个类型,代表整个类
java.lang.reflect.Method; //代表字节码中的方法字节码,代表类中的方法
java.lang.reflect.Constructor; //代表字节码中的构造方法节码,代表类中的构造方法
java.lang.reflect.Field; //代表字节码中的属性字节码,代表类中的成员变量)(静态变量)

class:
public class User{field:int no;
constructor:
public User(){}public User(int no){this.no=no;}
method:
public setNo(int no){this.no=no;}
public getNo(){return this.no;}
}

2.获取class的三种方式

要操作一个类的字节码,需要首先获取到这个类的字节码,怎么获取java.lang.class实例
三种方式
第一种:Class c=Class.forName(“完整类名带包名”);
第二种:Class c=对象.getClass();
第三种:Class c=任何类型.class;

2.1.Class.forName()方式

Class.forName();

  • 1.静态方法
  • 2.方法的参数是一个字符串
  • 3.字符串需要一个完整的类名
  • 4.完整类名必需带有包名,java.lang也不能省略
try {Class c1=Class.forName("java.lang.String");//c1代表String.class文件,或者说c1代表string类型Class c2=Class.forName("java.util.Date");   //c2代表Date类型Class c3=Class.forName("java.lang.Integer");//c3代表Integer类型Class c4=Class.forName("java.lang.System");//c4代表System类型} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}

2.2.obj.getClass()方式


java中任何一个对象都有一个方法:getClass();

String s="abc";Class x=s.getClass(); //x代表String.class字节码文件,x代表String类型System.out.println(c1==x);   //true(==判断的是对象的内存地址)Date time=new Date();Class y=time.getClass();//true(c2和y两个变量中保存的内存地址都是一样的,都指向方法区中的字节码文件)System.out.println(c2==y);

注意:以上代码中c1和c2是上一种方式得到的变量

2.3…class方式

java语言中任何一种数据类型,包括基本数据类型,它都有.class属性

Class z=String.class;       //z代表String类型
Class k=Date.class;            //k代表Date类型
Class f=int.class;         //f代表int类型
Class e=double.class;      //e代表double类型
System.out.println(c1==z);    //true

3.通过反射实例化对象

获取到Class能干什么
通过Class的newInstance()方法来实例化对象
注意:newInstance()方法内部实际上调用了无参构造方法,必须保证无参构造存在才可以

public class User {public User(){System.out.println("无参构造方法");}
}public class ReflectTest02 {public static void main(String[] args) {//这是不使用反射机制创建对象User user=new User();System.out.println(user);//下面这段代码是以反射机制的方式创建对象try {//通过反射机制,获取Class,通过Class来实例化对象Class c=Class.forName("reflect.User"); //c代表User对象//newInstance()这个方法会调用User这个类的无参数构造方法,来完成对象的创建//重点是:newInstance()调用的是无参构造,必须保证无参构造是存在的Object obj=c.newInstance();System.out.println(obj);} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InstantiationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();}}
}

4.通过读属性文件实例化对象

反射机制更灵活,灵活在哪里?
验证反射机制的灵活性
java代码写一遍,在不改变java源代码的基础之上,可以做到不同对象的实例化
非常之灵活,(符合OCP的原则,对扩展开放,对修改关闭)
后期要学习的是框架,而工作过程中,也都是使用高级框架,
这些高级框架底层实现原理,都采用了反射机制,所以反射机制是重要的,
学会了反射机制有利于你理解剖析底层的源代码
classInfo.properties的文件

className=cn.yujie.bean.User
public class ReflectTest01 {public static void main(String[] args) throws Exception{//这种方式代码就写死了,只能创建一个User类型的对象//User user=new User();//以下代码是灵活的,代码不需要改动,可以修改配置文件,配置文件修改之后,可以创建出不同的实例对象try {//通过IO流读取classInfo.properties文件FileReader reader=new FileReader("chapter15/classInfo.properties");//创建属性类对象MapProperties pro=new Properties();    //keyvalue都是String//加载pro.load(reader);//关闭流reader.close();//通过key获取valueString className=pro.getProperty("className");//通过反射机制实例化对象Class c=Class.forName(className);Object obj=c.newInstance();System.out.println(obj);} catch (FileNotFoundException e) {e.printStackTrace();}}
}

5.只让静态代码快执行可以使用forName

public class ReflectTest02 {public static void main(String[] args) {try {Class.forName("cn.yujie.reflect.MyClass");} catch (ClassNotFoundException e) {e.printStackTrace();}}
}
class MyClass{//静态代码块在类加载时执行,并且只执行一次static{System.out.println("MyClass类的静态代码块执行了!");}
}

记住:如果你只是希望一个类的静态代码快,其他代码一律不执行
你可以使用:
Class.forName(“完整类名”);
这个方法的执行会导致类加载,类加载时,静态代码块执行
这种方式的路径的缺点是:移植性差,在IDEA中默认的当前路径是project的根。
这个代码假设离开了IDEA,换到了其他位置,可能当前路径就不是project的根了,这时这个路径就无效了。
FileReader reader=new FileReader(“chapter15/classInfo.properties”);
接下来说一种比较通用的一种路径,即使代码换位置了,这样编写仍然是通用的
注意:使用以下通用方式的前提是:这个文件必须在类路径下
记住:凡是在src下的都是类路径下

怎么获取一个文件的绝对路径,以下讲解的这种方式是通用的,但前提是:文件需要在类路径下,才能使用这种方式。
Thread.currentThread()当前线程对象

  • getContextClassLoader()是线程对象的方法,可以获取到当前线程的类加载器对象
  • getResource()这是类加载器对象的方法,当前线程的类加载器默认从类的根路径下加载资源【获取资源】
  • getPath()获取绝对路径
//这种方式获取文件的绝对路径是通用的。
String path=Thread.currentThread().getContextClassLoader().getResource("classInfo2.properties").getPath();
System.out.println(path);//获取db.properties文件的绝对路径(从类的根路径下作为起点开始)
String path2=Thread.currentThread().getContextClassLoader().getResource("cn/yujie/bean/classInfo2.properties").getPath();
System.out.println(path2);

6.以流的形式直接返回

public class IOProPertiesTest {public static void main(String[] args) throws Exception{try {//获取一个文件的绝对路径
//            String path=Thread.currentThread().getContextClassLoader().getResource("classInfo2.properties").getPath();
//            FileReader reader=new FileReader(path);//直接以流的形式返回。InputStream reader=Thread.currentThread().getContextClassLoader().getResourceAsStream("classinfo2.properties");Properties pro=new Properties();pro.load(reader);reader.close();//通过key获取valueString className=pro.getProperty("className");System.out.println(className);} catch (FileNotFoundException e) {e.printStackTrace();}}
}

7.资源绑定器

java.util包下提供了一个资源绑定器,便于获取属性配置文件中的内容,
使用以下这种方式的时候,属性配置文件xxx.properties必须放到类路径下

public class ReSourceBundleTest {public static void main(String[] args) {//资源绑定器,只能绑定xxx.properties文件,并且这个文件必须在类路径下,文件扩展名必须是properties//并且在写路径的时候,路径后面的扩展名不能写ResourceBundle bundle =ResourceBundle.getBundle("classInfo2");String className=bundle.getString("className");System.out.println(className);}
}

8.类加载器

3、关于JDK中自带的类加载器:(聊一聊,不需要掌握,知道当然最好!)
什么是类加载器?

  • 专门负责加载类的命令/工具。
  • ClassLoader
    JDK中自带了3个类加载器
  • 启动类加载器:rt.jar
  • 扩展类加载器:ext/*.jar
  • 应用类加载器:classpath

假设有这样一段代码:
String s = “abc”;

  代码在开始执行之前,会将所需要类全部加载到JVM当中。通过类加载器加载,看到以上代码类加载器会找String.class文件,找到就加载,那么是怎么进行加载的呢
  首先通过“启动类加载器”加载。注意:启动类加载器专门加载:C:\Program Files\Java\jdk1.8.0_101\jre\lib\rt.jar
  rt.jar中都是JDK最核心的类库
  如果通过“启动类加载器”加载不到的时候,会通过"扩展类加载器"加载
  注意:扩展类加载器专门加载:C:\Program Files\Java\jdk1.8.0_101\jre\lib\ext*.jar
  如果“扩展类加载器”没有加载到,那么会通过“应用类加载器”加载。注意:应用类加载器专门加载:classpath中的类

9.双亲委派机制

java中为了保证类加载的安全,使用了双亲委派机制
优先从启动类加载器中加载,这个称为“父” “父”无法加载到,再从扩展类加载器中加载,这个称为“母”。双亲委派。如果都加载不到,才会考虑从应用类加载器中加载。直到加载到为止

10.总结

1.什么是反射机制?反射机制有什么用?
反射机制:可以操作字节码文件
作用:可以让程序更加灵活。

2.反射机制相关的类在哪个包下?
java.lang.reflect.*;

3.反射机制相关的主要的类?

  • java.lang.Class
  • java.lang.reflect.Method;
  • java.lang.reflect.Constructor;
  • java.lang.reflect.Field;

4.在java中获取Class的三种方式?
第一种:

  • Class c = Class.forName(“完整类名”);
    第二种:
  • Class c = 对象.getClass();
    第三种:
  • Class c = int.class;
  • Class c = String.class;

5.获取了Class之后,可以调用无参数构造方法来实例化对象

//c代表的就是日期Date类型Class c = Class.forName("java.util.Date");
//实例化一个Date日期类型的对象Object obj = c.newInstance();

一定要注意:
newInstance()底层调用的是该类型的无参数构造方法
如果没有这个无参数构造方法会出现"实例化"异常

6.如果你只想让一个类的“静态代码块”执行的话,你可以怎么做?

  • Class.forName(“该类的类名”);
  • 这样类就加载,类加载的时候,静态代码块执行!!!!
  • 在这里,对该方法的返回值不感兴趣,主要是为了使用“类加载”这个动作。

7.关于路径问题?

String path = Thread.currentThread().getContextClassLoader().getResource("写相对路径,但是这个相对路径从src出发开始找").getPath(); String path = Thread.currentThread().getContextClassLoader().getResource("abc").getPath();   //必须保证src下有abc文件。String path = Thread.currentThread().getContextClassLoader().getResource("a/db").getPath(); //必须保证src下有a目录,a目录下有db文件。
String path = Thread.currentThread().getContextClassLoader()
.getResource("com/bjpowernode/test.properties").getPath();
//必须保证src下有com目录,com目录下有bjpowernode目录。
//bjpowernode目录下有test.properties文件。

这种方式是为了获取一个文件的绝对路径。(通用方式,不会受到环境移植的影响。)但是该文件要求放在类路径下,换句话说:也就是放到src下面。src下是类的根路径。

直接以流的形式返回:

InputStream in = Thread.currentThread().getContextClassLoader()                 .getResourceAsStream("com/bjpowernode/test.properties");

8.IO + Properties,怎么快速绑定属性资源文件?

//要求:第一这个文件必须在类路径下
//第二这个文件必须是以.properties结尾。
ResourceBundle bundle = ResourceBundle.getBundle("com/bjpowernode/test");
String value = bundle.getString(key);

Java基础-反射机制相关推荐

  1. [Java基础] 反射机制汇总

    引言 初学Java反射机制的时候,只是感觉很神奇,但是不知道学了该怎么用,所以过了一段时间就忘得差不多了:最近接触到了框架,在学习中遇到了反射,深深体会到了反射机制的神奇,回来复习了一下反射机制,写一 ...

  2. 【java基础】java的反射机制

    1.简介 java的反射机制是java的特性之一,反射技术是构建框架技术的基础所在. java的反射机制,是指在运行状态中,对于任意一个类,都能知道这个类的所有属性和方法,对于任意一个对象,都能调用它 ...

  3. Java语言基础-反射机制、正则表达式

    反射机制 反射机制是在运行状态中,对于任意一个类,都能知道这个类(class文件)的所有属性和方法. 对于任意一个对象,都能调用它的任意一个方法和属性. 这种动态获取信息以及动态调用对象的方法的功能称 ...

  4. Java的反射机制 工厂模式综合讲解【转载自51CTO】

    2019独角兽企业重金招聘Python工程师标准>>> Java的反射机制 工厂模式综合讲解 1.什么叫反射 Java.lang.reflect包下 正常情况下我们可以通过类实例化一 ...

  5. 什么是Java的反射机制

    Java反射机制是Java的特点,是框架实现的基础,百度结果: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这 ...

  6. 什么是Java的反射机制?

    Java 的反射机制是使其具有动态特性的非常关键的一种机制,也是在JavaBean 中广泛应用的一种特性. 运用JavaBean 的最常见的问题是:根据指定的类名,类字段名和所对应的数据,得到该类的实 ...

  7. java中反射机制的含义_java的反射是什么意思?

    反射是Java的特征之一,是一种间接操作目标对象的机制. Java反射机制指的是在Java程序运行状态中,对于任何一个类,都可以获得这个类的所有属性和方法:对于给定的一个对象,都能够调用它的任意一个属 ...

  8. 16、Java 基础-反射

    Java 反射 1.反射 反射是指程序可以访问.检测.修改它本身的状态或行为的一种能力. 2.Java的反射机制 java的反射机制是指在程序的运行状态中,给定任意一个类,都可以获取到这个累的属性和方 ...

  9. Java的反射机制,内含超简单实例代码(搞懂反射,这一篇就够了)

    一 首先来说说反射机制的概念: 程序在运行时, 对于类来说,可以知道该类的任意属性和方法: 对于对象来说,可以调用该对象的任意方法和属性: 就以上这种动态获取信息的机制就称为Java的反射机制 彻底了 ...

最新文章

  1. 认识RAID磁盘阵列
  2. vue.js 2.0实现的简单分页
  3. 李宏毅机器学习课程8~~~keras
  4. ajax当页post请求,tag落地页--通过ajax-post请求数据
  5. java中的 =运算符_(二十七)、java中的运算符
  6. 浙江大学2009年数学分析考研试题第7题参考解答
  7. CSS 之 样式优先级机制
  8. android room_Android Room –待办事项清单应用程序
  9. 脚本故事 - 2003年11月
  10. freemarker判断对象是否为空
  11. qq音乐linux版本下载地址,qq音乐linux版本下载
  12. 价值函数与贝尔曼方程
  13. 高分Essay写作要点分析
  14. KMPlayer 一打开总是出现右面的窗口 导航区 怎样设置不会自动打开
  15. 谷歌,互联网界的“彩蛋狂魔”
  16. 【计算分段函数】输入整数x和a,计算并输出分段函数的值(保留2位小数)。
  17. 7.2 MVC 实现登录验证
  18. 江西理工大学计算机网络基础试卷,无线网络技术作业(江西理工大学期末复习)...
  19. java三层架构实现登录_用户登录——三层架构
  20. totolinkn200up怎么设置_TOTOLINK N200UP无线网卡驱动

热门文章

  1. 美团点评:摩拜贡献收入15亿元 同期亏损45.5亿元
  2. SIP应答代码【ZT】
  3. java播放声音类和一个简单示例
  4. 计算机应用人机对话,什么是“人机对话”
  5. androidstudio做登录界面_Vue-cli+Element-ui实现后台管理系统(二)实现后台登录功能...
  6. 和华为杯_新闻|“华为杯”足球赛正式开展:我院女足小组赛拿下首胜
  7. mediasoup 安裝
  8. 【linux】linux 安装 protobuf 2.5.0 版本
  9. 【Elasticsearch】 es Bootstrap Checks Failed
  10. 【Json】JSONPath之fastJson与Snack3的使用介绍与区别