JAVA中的反射
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了JAVA中的反射,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含7057字,纯文字阅读大概需要11分钟。
内容图文
![JAVA中的反射](/upload/InfoBanner/zyjiaocheng/798/2a89f9512f3b485fbec5a7eb79c4d6ad.jpg)
一.反射的概述
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。
要想剖解一个类,必选要获取该类的字节码文件对象。而解剖使用的就是Class类中的方法。
反射就是把Java类中的各种成分映射成一个个的Java对象。
二.反射的理解
反射之中包含了一个「反」字,所以想要解释反射就必须先从「正」开始解释。
一般情况下,我们使用某个类时必定知道它是什么类,是用来做什么的。于是我们直接对这个类进行实例化,之后使用这个类对象进行操作。
正这进入这个类:
Person per=new Person();
per.setAge(10);
反着进入这个类,拿到字节码。
perClazz=Class.forName("reflect.Person");
Person per=(Person)perClazz.newInstance();
per.setAge(23);
可能需要添加抛出的异常。自行解决。
三.反射的使用
1.获取Class对象的三种方式:
a.Class.forNmae(全类)
b.类名.class
c.对象.getClass()
首先建立一个Person类:
package reflect;
public class Person implements MyInterface{
private int id;
private String name;
private int age;
public String desc;
public Person(int id, String name, int age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
public Person() {
}
public Person(int id) {
super();
this.id = id;
}
private Person(int id, String name) {
super();
this.id = id;
this.name = name;
}
private void privateMethod() {
System.out.println("private method");
}
public void publicMethod() {
System.out.println("public method");
}
private void publicMethod2(String name) {
System.out.println("public method "+name);
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
第一个方法:
try {
//引号中的是包名.类名
Class<?> perClaszz1=Class.forName("reflect.Person");
System.out.println(perClaszz1);
}catch(ClassNotFoundException e)
{
e.printStackTrace();
}
第二个方法:
//2 类名.class
Class<?> perClaszz2=Person.class;
System.out.println(perClaszz2);
第三个方法:
//3 对象.getClass()
Person per=new Person();
Class<?> perClaszz3=per.getClass();
System.out.println(perClaszz3);
注意:在运行期间,一个类,只有一个Class对象产生。
四.通过反射获取构造方法并使用,获取指定的构造方法
//获取该类得构造方法:
public static void demo05() {
try {
Class<?> perClazz = Class.forName("reflect.Person");
Constructor<?>[] constructors=perClazz.getConstructors();
for(Constructor<?> con:constructors)
{
System.out.println(con);
}
} catch (ClassNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
这个方法只是获取到里面的public的构造方法,但是并没有的到private的构造方法。
Constructor<?>[] constructors=perClazz.getConstructors();获取public饿构造方法
Constructor<?>[] constructors=perClazz.getDeclaredConstructors();获取public,private的构造方法。
得到某一个指定的构造方法。
Class<?> perClazz = Class.forName("reflect.Person");
//int类和Integer时两个类 ,是不相同的类.
Constructor<?> constructor=perClazz.getDeclaredConstructor(int.class);
//那私有的话那么需要的时:getDeclaredConstructor 如果拿共有的话 那么需要的时:getConstructors
//constructor.setAccessible(true);
System.out.println(constructor);
对构造方法的使用,通过构造方法进行new一个对象出来
通过构造方法进行 new一个新得对象出来
因为里面是,无参构造 所以 里面不需要传值
//通过构造方法进行 new一个新得对象出来
Constructor<?> constructor1=perClazz.getDeclaredConstructor();
Person instance=(Person)constructor1.newInstance();
System.out.println(instance);
指定一个
指定这个
/*
public Person(int id) {
super();
this.id = id;
}
*/
Constructor<?> constructor2=perClazz.getDeclaredConstructor(int.class);
Person instance1=(Person)constructor2.newInstance(12);
System.out.println(instance1.getId());
五.获取成员变量的使用
获取成员变量:
//获取该类得属性 也有公共属性 和 私有属性
//这里是获取所有得公共属性
public static void demo06() {
Class<?> perClazz;
try {
perClazz = Class.forName("reflect.Person");
Field[] fields=perClazz.getFields();
////拿到得是 所有属性,但是不拿 接口中得 和 继承类中 得属性和方法是一样得
//Field[] defields=perClazz.getDeclaredFields();
for(Field field:fields) {
System.out.println(field);
}
} catch (ClassNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
这个是对属性的赋值。即使使用。
Class<?> perClazz=null;
Person per = null;
Field idField = null;
perClazz=Class.forName("reflect.Person");
per = (Person)perClazz.newInstance();
idField = perClazz.getDeclaredField("id");
idField.setAccessible(true);
idField.set(per, 1);
System.out.println(per.getId());
六.一些其他的方法:
//获取所有得接口
public static void demo03() throws ClassNotFoundException {
Class<?> perClazz =Class.forName("reflect.Person");
Class<?>[] interfaces =perClazz.getInterfaces();
for(Class<?> inter:interfaces) {
System.out.println(inter);
}
}
//获取所有得父类
public static void demo04() {
Class<?> perClazz;
try {
//因为java不可以实现多继承,所以不需要for循环
perClazz = Class.forName("reflect.Person");
Class<?> superClass=perClazz.getSuperclass();
System.out.println(superClass);
} catch (ClassNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
//反射可以 越过泛型检查
public static void demo05() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
ArrayList<Integer> list=new ArrayList<>();
list.add(123);
//越过泛型检查得意思是:你约束的对象是int类型的,但是你添加了String类型的,是会报错的。
//list.add("zs");
//反射入口 一定要拿到
Class<?> listClazz=list.getClass();
Method method=listClazz.getMethod("add", Object.class);
method.invoke(list, "zs");
System.out.println(list);
//虽然可以这样子做,但是 不建议这样做,因为人家 已经 指定 这样子做了
}
七.动态加载 类名 和方法
在项目中新建一个class.txt 内容:
classname=reflect.Person
methodname=publicMethod
public static void demo04() throws FileNotFoundException, IOException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
Properties prop=new Properties();
prop.load(new FileReader("class.txt"));
String classname=prop.getProperty("classname");
String methodname=prop.getProperty("methodname");
Class<?> perClazz=null;
perClazz=Class.forName(classname);
Method method =perClazz.getMethod(methodname);
method.invoke(perClazz.newInstance());
}
八.通过一个类可以给任何属性赋值
一次一次拿到属性,给其赋值,比较麻烦,但是,调用一个方法类既可以实现:
//通过这个类可以给任何属性赋值
public class PropertyUtil {
public static void setProperty(Object obj,String propertyName,Object value) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
//通过反射拿到类
Class<?> clazz=obj.getClass();
//拿到该类的属性
Field field =clazz.getDeclaredField(propertyName);
field.setAccessible(true);
field.set(obj, value);
//上面的语句为,给obj的这个对象中的filed这个属性赋值value
}
}
然后再去主方法中:
public static void demo06() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
Person per=new Person();
PropertyUtil.setProperty(per, "name", "zs");
System.out.println(per.getName());
}
内容总结
以上是互联网集市为您收集整理的JAVA中的反射全部内容,希望文章能够帮你解决JAVA中的反射所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。