二.反射机制相关的重要的类及其常用方法
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
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://img-blog.csdnimg.cn/img_convert/8762d473d39207a8855dc7b555841089.jpeg)
最后
针对最近很多人都在面试,我这边也整理了相当多的面试专题资料,也有其他大厂的面经。希望可以帮助到大家。
最新整理面试题
上述的面试题答案都整理成文档笔记。也还整理了一些面试资料&最新2021收集的一些大厂的面试真题
最新整理电子书
最新整理大厂面试文档
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
1713513865006)]
[外链图片转存中…(img-yloRV8go-1713513865008)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://img-blog.csdnimg.cn/img_convert/8762d473d39207a8855dc7b555841089.jpeg)
最后
针对最近很多人都在面试,我这边也整理了相当多的面试专题资料,也有其他大厂的面经。希望可以帮助到大家。
最新整理面试题
[外链图片转存中…(img-dYzVvqAJ-1713513865010)]
上述的面试题答案都整理成文档笔记。也还整理了一些面试资料&最新2021收集的一些大厂的面试真题
最新整理电子书
[外链图片转存中…(img-ugCMTTJg-1713513865012)]
最新整理大厂面试文档
[外链图片转存中…(img-EqHXwAuZ-1713513865014)]
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!