《java学习笔记》之反射机制初步

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

二.反射机制相关的重要的类及其常用方法

2.1 java.lang.Class:

代表整个字节码,代表一个类型,代表整个类。

(一)获取class对象的三种方法

/*

  • 要操作一个类的字节码,首先要获取到这个类的字节码,怎么获取java.lang.Class实例?

  •   三种方式
    
  •           第一种: Class c = Class.forName("完整类名带包名");
    
  •           第二种: Class c =对象.getClass();
    
  •           第三种:  Class c =数据类型.class()
    
  • */

public class ReflectTest01 {

public static void main(String[] args) {

/*

  • Class.format()

  • 1.静态方法

  • 2.方法的参数是一个字符串

  • 3.字符串需要一个完整的类名

  • 4.完整类名必须带有包名,java.lang包也不能省

  • */

Class c1 = null;

try {

c1 = Class.forName(“java.lang.String”);//c1代表String.class文件,或者c1代表String类型

System.out.println(c1);//class java.lang.String

Class c2 = Class.forName(“java.util.Date”);//c2代表Date类型

System.out.println(c2);//class java.util.Date

Class c3 = Class.forName(“java.util.Random”);//c3代表Random类型

System.out.println(c3);//class java.util.Random

Class c4 = Class.forName(“java.math.BigDecimal”);//c4代表 BigDecimal 类型

System.out.println(c4);//class java.math.BigDecimal

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

//java中任何一个类都有一个方法:getClass()

String string = “abc”;

Class c5 = string.getClass();

//内存地址相同,都是指向 String 的字节码文件

System.out.println(c5 == c1);//true

//第三种方式:java中任何一种数据类型,包括基本数据类型,都有.class属性

Class c6 = String.class;

System.out.println(c6);//class java.lang.String

Class c7 = Integer.class;

System.out.println(c7);//class java.lang.Integer

Class c8 = double.class;

System.out.println(c8);//double

}

}

(二)通过class文件来实例化对象

/*

  • 通过Class的newInstance()方法来实例化对象

  • 注意:newInstance()方法内部实际上是调用了无参数构造方法,必须保证无参构造存在

  • */

public class ReflectTest02 {

public static void main(String[] args) {

//获取字节码对象

try {

Class c = Class.forName(“javasetest.bean.User”);//完整类名带包名

//通过 class 文件来实例化对象

Object o1 = c.newInstance();//调用了无参数构造方法

System.out.println(o1);

//无参构造方法执行

//javasetest.bean.User@6bdf28bb

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

} catch (InstantiationException e) {

e.printStackTrace();

}

}

}

import java.io.FileNotFoundException;

import java.io.FileReader;

import java.io.IOException;

import java.util.Properties;

/*

  • 验证反射机制的灵活性

  • java代码写一次,在不改变java源代码的基础上,可以做到不同对象的实例化

  • 非常之灵活(符合OCP原则:对拓展开放,对修改关闭)

  • */

public class ReflectTest03 {

public static void main(String[] args) {

//通过IO流读取calssinfo.porperties文件

FileReader fileReader =null;

//创建Map对象

Properties properties = new Properties();

try {

fileReader = new FileReader(“C:\IdeaProjects\chapter25 反射机制\src\classinfo2.properties”);

//将文件中的内容下载到 properties 中

properties.load(fileReader);

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

} finally {

try {

//关闭流

fileReader.close();

} catch (IOException e) {

e.printStackTrace();

}

}

//通过key获取value

String value = properties.getProperty(“className”);

System.out.println(value);

//创建类对象

Class c =null;

try {

//类名带包名,获得 字节码文件

c = Class.forName(value);

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

//实例化对象

Object object = null;

try {

object = c.newInstance();

} catch (InstantiationException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

}

System.out.println(object);

}

}

import javasetest.bean.Vip;

import java.lang.reflect.Constructor;

//使用反射机制创建对象

public class ReflectTest11 {

public static void main(String[] args) throws Exception {

//不使用放射机制怎么创建对象

Vip vip1 = new Vip();

Vip vip2 = new Vip(123,“钢铁侠”,“2008-4-14”,true);

//使用反射机制

//获取类

Class vipClass = null;

try {

vipClass = Class.forName(“javasetest.bean.Vip”);

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

//使用无参构造

Object o1 = vipClass.newInstance();

System.out.println(o1);//Vip{no=0, name=‘null’, birth=‘null’, sex=false}

//调用有参的构造方法

//第一步:先获取到这个有参的构造方法

//参数是class

Constructor constructor = vipClass.getDeclaredConstructor(int.class,String.class,String.class,boolean.class);

//第二步:调用构造方法new对象

Object o2 = constructor.newInstance(123,“美国队长”,“2001-9-9”,true);

System.out.println(o2);//Vip{no=123, name=‘美国队长’, birth=‘2001-9-9’, sex=true}

}

}

(三)了解 Class.forName()

/*

  • 研究一下,Class.forName()发生了什么

  • 如果你只是希望一个类的静态代码块执行,其余的代码一律不执行

  • 可以使用:

  •       Class.forName("完整类名");
    
  •       这个方法的执行会导致类加载,类加载时,静态代码块执行
    
  •       JDBC会使用
    
  • */

public class ReflectTest04 {

public static void main(String[] args) {

try {

Class c = Class.forName(“javasetest.reflect.MyClass”);//静态方法执行

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

}

}

class MyClass{

static {

System.out.println(“静态方法执行”);

}

public MyClass() {

System.out.println(“无参构造执行”);

}

}

2.2 java.lang.reflect.Method
(一)反射类当中所有的Method

import java.lang.reflect.Method;

import java.lang.reflect.Modifier;

//如何通过反射机制获取方法

public class reflectTest08 {

public static void main(String[] args) {

//获取类

Class userServiceClass = null;

try {

userServiceClass = Class.forName(“javasetest.UserService”);

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

//获取所有的方法

Method[] methods = userServiceClass.getDeclaredMethods();

//看一下有多少方法

System.out.println(methods.length);//2

//遍历

for (Method method : methods){

//修饰符列表

System.out.println(Modifier.toString(method.getModifiers()));

//获取返回值类型

System.out.println(method.getReturnType().getSimpleName());

//获取方法名

System.out.println(method.getName());

//方法参数的修饰符列表

Class[] parameterTypes = method.getParameterTypes();

for(Class p:parameterTypes){

System.out.println(p.getSimpleName());

}

}

}

}

(二)通过反射机制调用对象的方法

import javasetest.UserService;

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

/*

  • 重点:必须掌握

  • 通过反射机制再怎么调用一个对象的方法

  • */

public class reflectTest09 {

public static void main(String[] args) {

//不使用反射机制怎么调用方法?

UserService user1 = new UserService();

//调用方法

boolean log1 = user1.login(“钢铁侠”,“123”);

System.out.println(log1);//true

//使用反射机制

Class userServiceClass = null;

try {

userServiceClass = Class.forName(“javasetest.UserService”);

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

//创建对象

Object object = null;

try {

object = userServiceClass.newInstance();

} catch (InstantiationException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

}

//获取方法

Method methodLog = null;

try {

methodLog = userServiceClass.getMethod(“login”,String.class,String.class);

} catch (NoSuchMethodException e) {

e.printStackTrace();

}

//调用方法

Object log2 = false;

try {

log2 = methodLog.invoke(object,“美国队长”,“321”);

} catch (IllegalAccessException e) {

e.printStackTrace();

} catch (InvocationTargetException e) {

e.printStackTrace();

}

System.out.println(log2);//false

}

}

2.3 java.lang.reflect.Constructor

import java.lang.reflect.Constructor;

import java.lang.reflect.Modifier;

/*

反编译一个类的Constructor构造方法

  • */

public class ReflectTest10 {

public static void main(String[] args) throws Exception{

StringBuilder s= new StringBuilder();

Class vipClass = Class.forName(“javase.bean.Vip”);

s.append(Modifier.toString(vipClass.getModifiers()));

s.append(" class ");

s.append(vipClass.getSimpleName());

s.append(“{\n”);

//拼接构造方法

Constructor[] constructors = vipClass.getDeclaredConstructors();

for (Constructor constructor : constructors){

s.append(“\t”);

s.append(Modifier.toString(constructor.getModifiers()));

s.append(" ");

s.append(vipClass.getSimpleName());

s.append(“(”);

//拼接参数

Class[] parameterTypes = constructor.getParameterTypes();

for (Class p: parameterTypes){

s.append(p.getSimpleName());

s.append(“,”);

}

if (parameterTypes.length > 0){

s.deleteCharAt(s.length() - 1);

}

s.append(“){}\n”);

}

s.append(“}”);

System.out.println(s);

}

}

2.4 java.lang.reflect.Field:

代表字节码中的属性字节码。代表类中的成员变量(静态变量+实例变量)。

(一)反射类当中所有的Field

import java.lang.reflect.Field;

import java.lang.reflect.Modifier;

/*

  • 反射Student类当中所有的Field(了解)

  • */

public class ReflectTest05 {

public static void main(String[] args) {

//获取整个类

try {

Class studentClass = Class.forName(“javasetest.bean.Student”);

//获取类的名字

String stringName = studentClass.getName();

System.out.println("完整类名 " + stringName);//完整类名 javasetest.bean.Student

//获取类的简单名字

String stringSimpleName = studentClass.getSimpleName();

System.out.println("简单类名 " + stringSimpleName);//简单类名 Student

最后

小编精心为大家准备了一手资料

以上Java高级架构资料、源码、笔记、视频。Dubbo、Redis、设计模式、Netty、zookeeper、Spring cloud、分布式、高并发等架构技术

【附】架构书籍

  1. BAT面试的20道高频数据库问题解析
  2. Java面试宝典
  3. Netty实战
  4. 算法

BATJ面试要点及Java架构师进阶资料

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!
s.forName(“javasetest.bean.Student”);

//获取类的名字

String stringName = studentClass.getName();

System.out.println("完整类名 " + stringName);//完整类名 javasetest.bean.Student

//获取类的简单名字

String stringSimpleName = studentClass.getSimpleName();

System.out.println("简单类名 " + stringSimpleName);//简单类名 Student

最后

小编精心为大家准备了一手资料

[外链图片转存中…(img-NSVUAqES-1714773716365)]

[外链图片转存中…(img-mswFey0h-1714773716366)]

以上Java高级架构资料、源码、笔记、视频。Dubbo、Redis、设计模式、Netty、zookeeper、Spring cloud、分布式、高并发等架构技术

【附】架构书籍

  1. BAT面试的20道高频数据库问题解析
  2. Java面试宝典
  3. Netty实战
  4. 算法

[外链图片转存中…(img-HWxD3lqu-1714773716366)]

BATJ面试要点及Java架构师进阶资料

[外链图片转存中…(img-WsQahzSv-1714773716367)]

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

  • 23
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值