Java - 基础 - 反射
2021/9/21 9:57:25
本文主要是介绍Java - 基础 - 反射,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
Java - 基础 - 反射
- 反射机制
- 1.认识反射
- 2.Class类对象实例化
- 3.反射实例化对象
- 4.反射调用构造
- 5 .反射调用方法
- 6.反射调用成员
- 7.总结
反射机制
-
什么是反射
-
反射的作用
-
利用反射调用类结构
1.认识反射
正:正常情况下,先有类,之后才会有类的对象
反:可以利用对象找到对象的出处
取得Classs对象:
public final Class<?> getClass()
该方法继承自Object类,所以,所有的类都有这个方法
public static void main(String[] args) { Date date = new Date(); System.out.println(date.getClass()); } //输出: //class java.util.Date
2.Class类对象实例化
java.lang.Class是一个类。该类是反射的源头,该类有三种实例化方法,如下:
-
调用Object类中的getClass()方法
public static void main(String[] args) { Date date = new Date(); Class <?> cls = date.getClass(); System.out.println(cls); }
-
使用"类.class"取得
public static void main(String[] args) { Class <?> cls = Date.Class; System.out.println(cls); }
-
调用Class类提供的方法
实例化Class对象:
public static Class<?> forName(String className)
throws ClassNotFoundExceptionpublic static void main(String[] args) { Class <?> cls = Class.forName("java.util.Date"); System.out.println(cls); }
此时可以不使用import进行导入
3.反射实例化对象
当拿到一个类的时候,使用new 实例化对象。如果存在Class类对象,就可以通过反射进行对象的实例化
实例化对象方法:
public T newInstance() throws InstantiationException, IllegalAccessException
示例
class Book{ public Book() { System.out.println("********************"); } public String toString() { return "这是一本书"; } } public class test { public static void main(String[] args) throws Exception { //1.常规方法,new对象 Book b = new Book(); System.out.println(b); //2.反射对象 Class<?> cls = Class.forName("com.String.Book"); Object o = cls.newInstance(); Book book = (Book)o; System.out.println(o);//输出b和o结果一样 } }
4.反射调用构造
当类中只有有参构造的时候,通过反射调用,会产生异常
错误代码示例
package com.String; public class test { public static void main(String[] args) throws Exception { Class<?> cls = Class.forName("com.t.Book"); Object o = cls.newInstance(); System.out.println(o); } }
Book类,位于其他包
package com.t; public class Book{ private String title; private double price; public Book(String title , double price) { this.title = title ; this.price = price; } public String toString() { return "书名:"+this.title+",价格:"+this.price; } }
异常信息
Exception in thread "main" java.lang.InstantiationException: com.t.Book at java.lang.Class.newInstance(Unknown Source) at com.String.test.main(test.java:11) Caused by: java.lang.NoSuchMethodException: com.t.Book.<init>() at java.lang.Class.getConstructor0(Unknown Source) ... 2 more
解决方法:
在Class类中,提供有获取构造方法的方法
-
取得全部构造方法:
public Constructor <?> [] getConstructors()
-
取得一个指定参数的构造方法:
public Constructor < T > getConstructor(Class<?>… parameterTypes)
上面两个方法的返回值**Constructor **是java.lang.reflect.Constructor类的对象,在这个类中提供有一个明确传递有参构造内容的实例化对象方法
public T newInstance(Object... initargs)
解决代码示例:
package com.String; import java.lang.reflect.Constructor; public class test { public static void main(String[] args) throws Exception { Class<?> cls = Class.forName("com.t.Book"); Constructor<?> con = cls.getConstructor(String.class,double.class); Object o = con.newInstance("java开发",79.8); System.out.println(o); } }
简单JAVA类的开发之中,至少保留一个无参构造,反射调用不方便
5 .反射调用方法
类中的普通方法,只有在类产生实例化对象之后才可以调用。
实例化对象的方式有三种
- new一个对象
- 克隆一个对象
- 反射一个对象
在Class类中,提供有取得方法的操作
-
取得一个类中的全部方法
public Method[] getMethods()
-
取得指定名称的方法
public Method getMethod(String name, Class<?>... parameterTypes)
name是方法名称
上面两个方法的返回值**Method **是java.lang.reflect.Method 类的对象
-
调用方法:
public Object invoke(Object obj, Object... args)
示例代码
Book类,位于其他包
package com.t; public class Book{ private String title; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } }
调用方法:
package com.String; import java.lang.reflect.Method; public class test { public static void main(String[] args) throws Exception { String fielName = "title"; Class<?> cls = Class.forName("com.t.Book"); Object o = cls.newInstance(); Method setMet = cls.getMethod("set" +initcap(fielName), String.class); Method getMet = cls.getMethod("get" +initcap(fielName)); setMet.invoke(o, "java开发"); System.out.println(getMet.invoke(o)); } //首字母大写 public static String initcap(String str) { return str.substring(0, 1).toUpperCase()+str.substring(1); } }
6.反射调用成员
类中的属性,一定要在本类实例化对象产生之后才可以分配内存空间
-
取得全部成员
public Field[] getDeclaredFields()
-
取得指定成员
public Field getDeclaredField(String name)
上面两个方法的返回值Field是java.lang.reflect.Field类的对象,该类提供有如下常用方法
-
取得属性内容
public Object get(Object obj)
-
设置属性内容
public void set(Object obj,Object value)
使用示例:
Book类,位于其他包
package com.t; public class Book{ private String title; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } }
反射调用:
package com.String; import java.lang.reflect.Field; public class test { public static void main(String[] args) throws Exception { //1.实例化类对象 Class<?> cls = Class.forName("com.t.Book"); Object o = cls.newInstance(); //取得成员 Field titleField = cls.getDeclaredField("title"); //取消封装,不取消无法访问private变量 titleField.setAccessible(true); //设置成员变量 titleField.set(o, "python"); System.out.println(titleField.get(o)); } }
构造方法和普通方法也可以取消封装
7.总结
- 实例化对象的方式多了一种:反射
- 简单JAVA类需要使用无参构造以及使用set\get方法的原因
这篇关于Java - 基础 - 反射的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南