一、什么是反射:
Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。而这也是Java被视为动态(或准动态,为啥要说是准动态,因为一般而言的动态语言定义是程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。)语言的一个关键性质。
二、反射机制主要提供以下功能:
①在运行时判断任意一个对象所属的类;
②在运行时构造任意一个类的对象;
③在运行时判断任意一个类所具有的成员变量和方法;
④在运行时调用任意一个对象的方法;
⑤生成动态代理。
三、反射机制的优缺点
1、优点:
在运行时获得类的各种内容,进行反编译,对于Java这种先编译再运行的语言,能够让我们很方便的创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代码的链接,更加容易实现面向对象。
2、缺点:
(1)反射会消耗一定的系统资源,因此,如果不需要动态地创建一个对象,那么就不需要用反射;
(2)反射调用方法时可以忽略权限检查,因此可能会破坏封装性而导致安全问题。
四、反射的作用
-
- 动态创建对象
- 动态操作属性
- 动态调用方法
在JDK中,主要由以下类来实现Java反射机制,这些类都位于java.lang.reflect包中
-
六、Class类的常用方法:
getFields()—— 获得类的public类型的属性。
getDeclaredFields()—— 获得类的所有属性
getField(String name)—— 获得类的指定属性
getMethods()—— 获得类的public类型的方法
getMethod (String name,Class [] args)—— 获得类的指定方法
getConstrutors()—— 获得类的public类型的构造方法
getConstrutor(Class[] args)—— 获得类的特定构造方法
newInstance()—— 通过类的无参构造方法创建对象
getName()—— 获得类的完整名字
getPackage()—— 获取此类所属的包
getSuperclass()—— 获得此类的父类对应的Class对象
七、代码演示:认知Class类
-
public class TestClass1 { public static void main(String[] args) throws Exception { //1.获取一个类的结构信息(类对象 Class对象) Class clazz = Class.forName("com.bjsxt.why.Dog"); //2.从类对象中获取类的各种结构信息 //2.1 获取基本结构信息 System.out.println(clazz.getName()); System.out.println(clazz.getSimpleName()); System.out.println(clazz.getSuperclass()); System.out.println(Arrays.toString(clazz.getInterfaces())); //2.2 获取构造方法 //只能得到public修饰的构造方法 //Constructor[] constructors = clazz.getConstructors(); //可以得到所有的构造方法 Constructor[] constructors = clazz.getDeclaredConstructors(); System.out.println(constructors.length); for(Constructor con :constructors){ //System.out.println(con.toString()); System.out.println(con.getName() + "||" + Modifier.toString(con.getModifiers())+" ||" + Arrays.toString(con.getParameterTypes())); } //Constructor con = clazz.getConstructor();//获取无参数构造方法 //Constructor con = clazz.getConstructor(String.class,String.class); Constructor con = clazz.getDeclaredConstructor(String.class,String.class); System.out.println(con); //2.3 获取属性 //Field[] fields = clazz.getFields(); Field [] fields = clazz.getDeclaredFields(); System.out.println(fields.length); for(Field f :fields){ System.out.println(f); } //Field f = clazz.getField("color"); //private 默认 protecte public都可以获取,但不包括父类的 Field f = clazz.getDeclaredField("age"); System.out.println(f); //2.3 获取方法 //Method[] methods = clazz.getMethods(); Method [] methods = clazz.getDeclaredMethods(); for(Method m : methods){ System.out.println(m); } //Method m = clazz.getMethod("shout",String.class); //Method m = clazz.getMethod("run");//public Method m = clazz.getDeclaredMethod("run"); System.out.println(m); } }
八、获取一个类的类对象的三种方式:
public class TestClass2 { public static void main(String[] args) throws Exception { //1.获取一个类的结构信息(类对象 Class对象) // 1.1Class.forName(类的完整路径字符串); //Class clazz = Class.forName("java.lang.String"); //1.2 类名.class // Class clazz = String.class; //1.3 对象名.getClass() String str = "bjsxt"; Class clazz = str.getClass(); //Integer in = new Integer(20); //2.从类对象中获取类的各种结构信息 System.out.println(clazz.getName()); System.out.println(clazz.getSimpleName()); System.out.println(clazz.getSuperclass()); System.out.println(Arrays.toString(clazz.getInterfaces())); } }
其中类名.class、对象名.getClass()方式在编码时已经知道了要操作的类,而Class.forName()方式在操作的时候,可以知道,也可以不知道要操作的类。所以当编码时还不知道要操作的具体类,就只能使用Class.forName()方式了。
九、实操:
1.创建项目,导入jar包
service层
servlet层
外部文件
testservlet实现效果
test01实现效果
test02实现效果
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/130143.html