Java反射是什么?看这篇绝对会了!

System.out.println(m[i].toString());

}

catch (Throwable e){

System.err.println(e);

}

}

}

public synchronized java.lang.Object java.util.Stack.pop()

public java.lang.Object java.util.Stack.push(java.lang.Object)

public boolean java.util.Stack.empty()

public synchronized java.lang.Object java.util.Stack.peek()

public synchronized int java.util.Stack.search(java.lang.Object)

这样就列出了java.util.Stack 类的各方法名以及它们的限制符和返回类型。这个程序使用Class.forName 载入指定的类,然后调用 getDeclaredMethods 来获取这个类中定义了的方法列表。java.lang.reflect.Methods 是用来描述某个类中单个方法的一个类。

以下示例使用 Class 对象来显示对象的类名:

void printClassName(Object obj) {

System.out.println("The class of " + obj +

" is " + obj.getClass().getName());

}

还可以使用一个类字面值(JLS Section 15.8.2)来获取指定类型(或 void)的 Class 对象。例如:

System.out.println("The name of class Foo is: "+Foo.class.getName());

在没有对象实例的时候,主要有两种办法。

//获得类类型的两种方式

Class cls1 = Role.class;

Class cls2 = Class.forName(“yui.Role”);

注意第二种方式中,forName中的参数一定是完整的类名(包名+类名),并且这个方法需要捕获异常。现在得到cls1就可以创建一个Role类的实例了,利用Class的newInstance方法相当于调用类的默认的构造器。

Object o = cls1.newInstance();

//创建一个实例

//Object o1 = new Role();   //与上面的方法等价

二.常用方法


1.isPrimitive(判断是否是基本类型的字节码)

public class TestReflect {

public static void main(String[] args) {

// TODO Auto-generated method stub

String str = “abc”;

Class cls1 = str.getClass();

Class cls2 = String.class;

Class cls3 = null;//必须要加上null

try {

cls3 = Class.forName(“java.lang.String”);

} catch (ClassNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(cls1==cls2);

System.out.println(cls1==cls3);

System.out.println(cls1.isPrimitive());

System.out.println(int.class.isPrimitive());//判定指定的 Class 对象是否表示一个基本类型。

System.out.println(int.class == Integer.class);

System.out.println(int.class == Integer.TYPE);

System.out.println(int[].class.isPrimitive());

System.out.println(int[].class.isArray());

}

}

结果:

true

true

false

true

false

true

false

true

2.getConstructor和getConstructors()

java中构造方法没有先后顺序,通过类型和参数个数区分。

public class TestReflect {

public static void main(String[] args) throws SecurityException, NoSuchMethodException {

// TODO Auto-generated method stub

String str = “abc”;

System.out.println(String.class.getConstructor(StringBuffer.class));

}

}

3.Filed类代表某一类中的一个成员变量。

import java.lang.reflect.Field;

public class TestReflect {

public static void main(String[] args) throws SecurityException, NoSuchMethodException, NoSuchFieldException, IllegalArgumentException, Exception {

ReflectPointer rp1 = new ReflectPointer(3,4);

Field fieldx = rp1.getClass().getField(“x”);//必须是x或者y

System.out.println(fieldx.get(rp1));

/*

* private的成员变量必须使用getDeclaredField,并setAccessible(true),否则看得到拿不到

*/

Field fieldy = rp1.getClass().getDeclaredField(“y”);

fieldy.setAccessible(true);//暴力反射

System.out.println(fieldy.get(rp1));

}

}

class ReflectPointer {

public int x = 0;

private int y = 0;

public ReflectPointer(int x,int y) {//alt + shift +s相当于右键source

super();

// TODO Auto-generated constructor stub

this.x = x;

this.y = y;

}

}

三.典型例题


1.将所有String类型的成员变量里的b改成a。

import java.lang.reflect.Field;

public class TestReflect {

public static void main(String[] args) throws SecurityException, NoSuchMethodException, NoSuchFieldException, IllegalArgumentException, Exception {

ReflectPointer rp1 = new ReflectPointer(3,4);

changeBtoA(rp1);

System.out.println(rp1);

}

private static void changeBtoA(Object obj) throws RuntimeException, Exception {

Field[] fields = obj.getClass().getFields();

for(Field field : fields) {

//if(field.getType().equals(String.class))

//由于字节码只有一份,用equals语义不准确

if(field.getType()==String.class) {

String oldValue = (String)field.get(obj);

String newValue = oldValue.replace(‘b’, ‘a’);

field.set(obj,newValue);

}

}

}

}

class ReflectPointer {

private int x = 0;

public int y = 0;

public String str1 = “ball”;

public String str2 = “basketball”;

public String str3 = “itcat”;

public ReflectPointer(int x,int y) {//alt + shift +s相当于右键source

super();

// TODO Auto-generated constructor stub

this.x = x;

this.y = y;

}

@Override

public String toString() {

return “ReflectPointer [str1=” + str1 + “, str2=” + str2 + “, str3=”

+ str3 + “]”;

}

}

2.写一个程序根据用户提供的类名,调用该类的里的main方法。

为什么要用反射的方式呢?

import java.lang.reflect.Field;

import java.lang.reflect.Method;

public class TestReflect {

public static void main(String[] args) throws SecurityException, NoSuchMethodException, NoSuchFieldException, IllegalArgumentException, Exception {

String str = args[0];

/*

* 这样会数组角标越界,因为压根没有这个字符数组

* 需要右键在run as-configurations-arguments里输入b.Inter(完整类名)

*

*/

Method m = Class.forName(str).getMethod(“main”,String[].class);

//下面这两种方式都可以,main方法需要一个参数

m.invoke(null, new Object[]{new String[]{“111”,“222”,“333”}});

m.invoke(null, (Object)new String[]{“111”,“222”,“333”});//这个可以说明,数组也是Object

/*

* m.invoke(null, new String[]{“111”,“222”,“333”})

* 上面的不可以,因为java会自动拆包

*/

}

}

class Inter {

public static void main(String[] args) {

for(Object obj : args) {

System.out.println(obj);

}

}

}

3.模拟 instanceof 操作符

class S {

}

public class IsInstance {

public static void main(String args[]) {

try {

Class cls = Class.forName(“S”);

boolean b1 = cls.isInstance(new Integer(37));

System.out.println(b1);

boolean b2 = cls.isInstance(new S());

System.out.println(b2);

}

catch (Throwable e) {

System.err.println(e);

}

}

}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

很多程序员,整天沉浸在业务代码的 CRUD 中,业务中没有大量数据做并发,缺少实战经验,对并发仅仅停留在了解,做不到精通,所以总是与大厂擦肩而过。

我把私藏的这套并发体系的笔记和思维脑图分享出来,理论知识与项目实战的结合,我觉得只要你肯花时间用心学完这些,一定可以快速掌握并发编程。

不管是查缺补漏还是深度学习都能有非常不错的成效,需要的话记得帮忙点个赞支持一下

整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!**

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

很多程序员,整天沉浸在业务代码的 CRUD 中,业务中没有大量数据做并发,缺少实战经验,对并发仅仅停留在了解,做不到精通,所以总是与大厂擦肩而过。

我把私藏的这套并发体系的笔记和思维脑图分享出来,理论知识与项目实战的结合,我觉得只要你肯花时间用心学完这些,一定可以快速掌握并发编程。

不管是查缺补漏还是深度学习都能有非常不错的成效,需要的话记得帮忙点个赞支持一下

整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值