一下均是来自己看自李兴华老师的视频笔记,他讲的视频挺好的,自己写的估计只能自己看的懂,想更加清楚的了解,请观看他的视频。
前天看那个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 + "]";
- }
- }
- 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);
- }
- }
五、操作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 + "]";
- }
- }
- 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]
我是只有一个参数的构造方法
Book [title=Android开发, price=0.0]
这就是反射的基本应用,一般都应用与框架中。