java 反射机制的基本知识
2016-07-22 20:24
543 查看
一下均是来自己看自李兴华老师的视频笔记,他讲的视频挺好的,自己写的估计只能自己看的懂,想更加清楚的了解,请观看他的视频。
前天看那个java学习路线的一张图上看了看,里面有一节内容讲的是反射,我就搜集资料视频学了学。
我们平常访问普通的方法都是在哪里进行使用new进行创建对象,再利用创建的对象进行访问这个方法。
那么我们如何在不使用new关键字的情况下进行访问这些对象和属性呢?new关键字是造成耦合度高的重要原因
Java 的反射就是在程序动态的运行中进行访问方法和属性;
一般来说创建并实例化一个程序一般有三种方法:通过new关键字 -- 通过 clon -- 另一种就是反射,今天说说反射。
先看一下怎么利用反射进行创建对象和实例化。
这样做出的应用更适用于更改信息,非开发人员更容易进行操作。
打印结果:Java开发
Field类就是一个动态访问类或接口的字段的入口。
打印结果
Book [title=Java开发, price=43.9]
我是只有一个参数的构造方法
Book [title=Android开发, price=0.0]
这样就可以进行控制方法了。
这就是反射的基本应用,一般都应用与框架中。
前天看那个java学习路线的一张图上看了看,里面有一节内容讲的是反射,我就搜集资料视频学了学。
我们平常访问普通的方法都是在哪里进行使用new进行创建对象,再利用创建的对象进行访问这个方法。
那么我们如何在不使用new关键字的情况下进行访问这些对象和属性呢?new关键字是造成耦合度高的重要原因
Java 的反射就是在程序动态的运行中进行访问方法和属性;
一般来说创建并实例化一个程序一般有三种方法:通过new关键字 -- 通过 clon -- 另一种就是反射,今天说说反射。
先看一下怎么利用反射进行创建对象和实例化。
一、利用反射进行创建对象和实例化。
Person类就不贴了,就是有两个属相private String name ,private int age,属性设置get set toString 方法package com.hejingzhou.tcoy; public class Test { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException { Person person = new Person(); Class cla_1 = person.getClass(); Object obj_1 = cla_1.newInstance(); System.out.println(obj_1); System.out.println("###############################"); Class cla_2 = Person.class; Object obj_2 = cla_2.newInstance(); System.out.println(obj_2); System.out.println("###############################"); Class cls_3 = Class.forName("com.hejingzhou.tcoy.Person"); System.out.println(cls_3);//获的是 完整的类 Object obj_3 = cls_3.newInstance(); //Person person = (Person)obj_3; //System.out.println(person.getAge()); System.out.println(obj_3); } }
二、反射创建对象实例的应用
interface IFruit{ void eat(); } class Apple implements IFruit{ public void eat() { // TODO Auto-generated method stub System.out.println("吃苹果"); } } class Orange implements IFruit{ public void eat() { // TODO Auto-generated method stub System.out.println("吃橘子"); } } class Factoty{ public static IFruit getInstance(String className) throws InstantiationException, IllegalAccessException, ClassNotFoundException{ //使用反射前的工厂模式,每次添加新的水果就得需要进行修改工厂模式类中的if语句 // if(className.equals("Apple")){ // return new Apple(); // } /*** * 使用后只需要填入类的详细类名就可以 */ IFruit fruit = null; fruit = (IFruit) Class.forName(className).newInstance(); return fruit; } } public class Test { public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException { //<span style="white-space:pre"> </span>Factoty.getInstance("Apple");//使用反射机制之前的工厂模式 IFruit fApple = Factoty.getInstance("com.hejingzhou.q.Orange"); fApple.eat(); } }
这样做出的应用更适用于更改信息,非开发人员更容易进行操作。
三、利用反射进行设置一个基本的属性
看一下这里的Book 类package com.hejingzhou.r; class Book { private String title; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String toString() { return "Book [title=" + title + "]"; } }Test一下
package com.hejingzhou.r; import java.lang.reflect.Field; public class Test { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException { Class cls = Class.forName("com.hejingzhou.r.Book"); Object obj = cls.newInstance(); Field titleField = cls.getDeclaredField("title"); titleField.setAccessible(true);//取消程序入口检查 否则title是private修饰的,是无法访问的 titleField.set(obj,"Java开发"); System.out.println(titleField.get(obj)); } }
打印结果:Java开发
Field类就是一个动态访问类或接口的字段的入口。
public Field getDeclaredField(String name) throws NoSuchFieldException, SecurityException Returns a Field object that reflects the specified declared field of the class or interface represented by this Class object. The name parameter is a String that specifies the simple name of the desired field.
public void setAccessible(boolean flag) throws SecurityException Set the accessible flag for this object to the indicated boolean value. A value of true indicates that the reflected object should suppress Java language access checking when it is used. A value of false indicates that the reflected object should enforce Java language access checks
set(Object obj, Object value) Sets the field represented by this Field object on the specified object argument to the specified new value.这样就可以动态的设置字段参数。
四、动态的设置构造方法
Book类必须有一个空参构造package com.hejingzhou.w; public class Book { private String title; private double price; public Book(){ } public Book(String title){ this.title = title; System.out.println("我是只有一个参数的构造方法"); } public Book(String title, double price) { super(); this.title = title; this.price = price; } public String toString() { return "Book [title=" + title + ", price=" + price + "]"; } }详细的管理构造参数一下
package com.hejingzhou.w; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class Test { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException { Class cls = Class.forName("com.hejingzhou.w.Book"); // Object apogee = cls.newInstance();//这样实例化 就只能调用 类中默认的无参构造方法 // System.out.println(obj); Constructor constructor = cls.getConstructor(new Class[]{String.class,double.class}); Object object = constructor.newInstance(new Object[]{new String("Java开发"),new Double(43.9)});//"Java开发",43.2 System.out.println(object); Constructor constructor2 = cls.getConstructor(new Class[]{String.class}); Object object2 = constructor2.newInstance(new Object[]{new String("Android开发")}); System.out.println(object2); } }这是java1.8环境下在进行构造方法赋值 的时候进行需要创建一个Object类型数组进行添加对应的数据,但是在视频中,是直接进行赋值的,这点需要注意,
五、操作get set 方法
Frult类(操作类)package com.hejingzhou.e; public class Fruit { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public String toString() { return "Fruit [name=" + name + "]"; } }进行设置操作get set方法的操作
package com.hejingzhou.e; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Test { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException { String fieldName = "name"; Class cla = Class.forName("com.hejingzhou.e.Fruit"); Object obj = cla.newInstance(); //System.out.println(obj); Method setMet = cla.getMethod("set"+initCap(fieldName), new Class[]{String.class}); Method getMet = cla.getMethod("get"+initCap(fieldName), null); setMet.invoke(obj,new Object[]{new String("java 开发")} ); System.out.println(getMet.invoke(obj, null)); } //返回字符串首字母大写 public static String initCap(String str){ return str.substring(0,1).toUpperCase()+str.substring(1); } }
打印结果
Book [title=Java开发, price=43.9]
我是只有一个参数的构造方法
Book [title=Android开发, price=0.0]
这样就可以进行控制方法了。
这就是反射的基本应用,一般都应用与框架中。
相关文章推荐
- Java反射学习 getClass()函数应用
- java反射实现javabean转json实例代码
- Java反射中常用的操作方法
- Java 反射
- java 通过反射获取调用类方法及属性
- Java高级编程 - 使用反射强制给private字段赋值
- Java高级编程 - 使用反射强制给private字段赋值
- java课堂练习,反射
- JAVA基础之反射
- java反射
- java基础反射
- Android获取apk签名信息(举例说明java反射调用方法步骤)
- 理解JAVA反射机制
- 黑马程序员---java基础加强 反射的深入理解
- 黑马程序员-----java基础java的反射机制
- java 通过反射获取调用类方法及属性
- java 反射调用带回调接口的函数
- JAVA反射
- 黑马程序员——【Java反射学习】Class类的使用
- 黑马程序员——【Java反射学习】方法的反射/成员变量的反射/构造函数的反射