您的位置:首页 > 编程语言 > Java开发

Java基础回顾 : 反射机制相关知识

2016-05-28 00:40 489 查看

★ . 反射机制的相关知识 : 

在Object 类之中定义了以下一个方法:

public final Class<?> getClass()
final修饰,所以此方法不能够被子类所覆写。这个方法上返回的是一个Class 类对象.

Class 类是一切反射的起源,而对于这个类的对象实例化方式一共分为三种:

· 第一种:利用对象中的getClass()方法;

· 第二种:利用“类.class”实现实例化,在WEB 开发的框架中会用到;

· 第三种:利用Class 类的一个静态方法操作:

public static Class<?> forName(String className) throws ClassNotFoundException    参数接收完整的“包.类”名称。

★ . Class 类之中定义的一个方法:

public T newInstance()throws InstantiationException,IllegalAccessException

此方法的主要功能是进行新对象的实例化操作。

比如说正常情况下,肯定是直接利用关键字new 进行对象的实例化,而现在除了使用 new 之外 , 还可以使用另外一种方式实例化 —— 反射机制。

从开发而言,使用最多的还是关键字new,或者在考虑代码进行解耦合性操作时才会考虑到使用反射。

★ . Class 类里面定义了如下的两个取得构造方法的操作:

public Constructor<?>[] getConstructors()throws SecurityException

public Constructor<T> getConstructor(Class<?>... parameterTypes)throws NoSuchMethodException,SecurityException

★ . Class 类之中定义有如下的取得类之中方法的操作:

· 取得类之中的全部普通方法

public Method[] getMethods() throws SecurityException

· 取得类之中的指定方法

public Method getMethod(String name,Class<?>... parameterTypes)throws NoSuchMethodException,SecurityException

在Method 类之中有一个非常重要的方法:

public Object invoke(Object obj,Object... args)throws IllegalAccessException,IllegalArgumentException,InvocationTargetException

invoke 的单词表示的是调用,实际上指的就是调用指定的对象操作方法。

eg : 

package example;

import java.lang.reflect.Method;

class Book{
private String title;

public Book(){}

public Book(String title){
this.title = title;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

@Override
public String toString() {
return "书名 : " + this.title;
}

}

public class TestDemo {
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("example.Book");

Object obj = clazz.newInstance();

//已经知道要操作属性的名称
String attributeName = "title";
Method setMet = clazz.getMethod("set" + initCap(attributeName), String.class);
Method getMet = clazz.getMethod("get" + initCap(attributeName));

setMet.invoke(obj, "Java开发"); //相当于对象.setTitle
System.out.println(getMet.invoke(obj));
}

/**
* 将一个字符串首字母大写
* @param str
* @return
*/
public static String initCap(String str){
return str.substring(0,1).toUpperCase() + str.substring(1);
}
}


★ . Class 类里面定义了可以取得类中属性的操作:

· 取得本类中定义的全部属性:

public Field[] getDeclaredFields()throws SecurityException

· 取得本类中定义的一个指定的属性

public Field getDeclaredField(String name)throws NoSuchFieldException,SecurityException

· 取得本类中public修饰的属性

public Field getField(String name)throws NoSuchFieldException,SecurityException


在Field 类之中有如下两个主要的方法:

· 设置属性内容:

public void set(Object obj,Object value)throws IllegalArgumentException,IllegalAccessException

· 取得属性内容:

public Object get(Object obj)throws IllegalArgumentException,IllegalAccessException

如果现在属性进行了封装,那么要想操作就必须取消封装,使用如下方法完成:

public void setAccessible(boolean flag)throws SecurityException

★ . 最后写一个利用反射机制的工厂设计模式:

package example;

interface Fruit{
public void eat();
}

class Apple implements Fruit {
@Override
public void eat() {
System.out.println("吃苹果.");
}
}
class Orange implements Fruit {
@Override
public void eat() {
System.out.println("吃橘子.");
}
}
class Cherry implements Fruit {
@Override
public void eat() {
System.out.println("吃樱桃.");
}
}

class FruitFactory {
public static Fruit getInstance(String className){
Fruit f = null;
try {
Class<?> clazz = Class.forName(className);
f = (Fruit) clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return f;
}
}

public class TestDemo {
public static void main(String[] args) throws Exception {
Fruit f = FruitFactory.getInstance("example.Cherry");
f.eat();
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息