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

java反射机制及应用分析

2017-07-14 16:59 302 查看
反射是java程序开发语言的特质之一,它允许运行中的java程序获取自身的信息,并且可以操作类或对象的内部属性。

当用户使用一个类的时候,应该先知道这个类,而后通过这个类产生实例化对象,但是“反”指的是通过对象找到类。

通过反射,我们可以在运行时获得程序或者程序中每一个类型的成员和成员的值。

java反射框架主要提供以下功能:

1 在运行时判断任意一个对象所属的类

2在运行时构造任意一个类的对象

3在运行时判断任意一个类所具有的成员变量和方法(通过反射甚至可以调用private方法)

4在运行时调用任意一个对象的方法

class Person{}

public class TestDemo{

public static void main(String [] args) throwsException{

Person per = new Person(); // 正 着操作

System.out.println(per.getClass().getName()); // 反射

}

}

getClass()方法返回的对象是Class类的对象。

想要取得这个类的实例化对象,有三种方式:

方式1:通过Object的getClass()方法取得,基本不用;

class Person{}

public class TestDemo{

public static void main(String [] args) throwsException{

Person per = new Person(); // 正 着操作

Class <?> cls = per.getClass(); //取得class对象

Systen.out.println(cls.getName());//反射

}

}

方式2:使用“类.class”取得

class Person{}

public class TestDemo{

public static void main(String [] args) throwsException{

Class <?> cls = Person.class; //取得class对象

Systen.out.println(cls.getName());//反射

}

}

方式3:使用Class类内部定义的一个static方法,使用频繁

class Person{}

public class TestDemo{

public static void main(String [] args) throwsException{

Class <?> cls = Class.fornName(“sai.xuexi.fanshe.peroson”); //取得class对象

Systen.out.println(cls.getName());//反射

}

}

新的问题: 取得clas类对象有什么用处呢?

对于对象的实例化操作之前一直依靠构造方法和关键字new完成,在有了class类对象之后,有有了一种提供对象的实例化方法。

例子:通过反射实例化对象

class Person{

public String toString(){

return "Person Class Instance."

}

}

public class TestDemo{

public static void main(String [] args) throwsException{

Person per = new Person(); // 正 着操作

Class <?> cls = Class.fornName(“sai.xuexi.fanshe.peroson”); //取得class对象

Object obj = cls.newInstance();//实例化对象,和使用关键字new一样

Person per = (person)obj;// 向下转型

Systen.out.println(per));//

}

}

使用反射实例化对象 可以减少耦合。(new是造成耦合的关键元凶)

反射在工厂方法中的使用:

 

interface Fruit{
public  void eat();
}
class Apple implements  Fruit{
public  void eat(){
System.out.print("chipingguo");
}
};
class Orange implements  Fruit{
public  void eat(){
System.out.print("chijuzi");
}
};
class Factory{
public static Fruit getInstance(String className){
Fruit f = null;
if("apple".equals(className)){
f = new Apple();
}
if ("orange".equals(className)){
f = new Orange();
}
return f;
}
}
public class Demo{
public static void mani (String args[]){
Fruit f = null;
f =Factory.getInstance("apple");
f.eat();
}
}


反射的深入应用:
以上只是利用Class类作为了反射实例化对象的基本应用,但是对于一个实例化对象而言,它需要调用类之中的构造方法,普通方法,属性。

1 调用构造方法:

调用构造方法有2种

方法1 取得一个类的全部构造方法:

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

方法2 取得一个类指定参数的构造方法:

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


方法1的应用:

class Person {
public Person() {}
public Person(String name) {}
public Person(String name,int age) {}
}
public class TestDemo {
public static void main(String[] args) throws Exception {
Class<?> cls = Class.forName("cn.mldn.demo.Person") ; // 取得Class对象
Constructor<?> cons [] = cls.getConstructors() ; // 取得全部构造
for(int x = 0; x < cons.length; x++) {
System.out.println(cons[x]);
}
}
}


方法2的应用

class Person {
private String name;
private int age;
public Person(String name,int age) {
this.name= name ;
this.age= age ;
}
@Override
public String toString() {
return"Person [name="+ name+ ", age="+ age+ "]";
}
}
public class TestDemo {
public static void main(String[] args) throws Exception {
Class<?> cls = Class.forName("cn.mldn.demo.Person") ; // 取得Class对象
// 取得指定参数类型的构造方法
Constructor<?> cons = cls.getConstructor(String.class,int.class) ;
Object obj = cons.newInstance("张三", 20); // 为构造方法传递参数
System.out.println(obj);
}
}


2 调用普通方法

public  Method [] getMethods() throws SecurityException; //  取得全部方法
// 取得指定方法
public Method getMethod(String name ,class<?> parameterTypes) throws SecurityException,NoSuchMethodException;


//取得一个类里面的全部方法
class Person {
private String name;
public void setName(String name) {
this.name= name;
}
public String getName() {
return name;
}
}
public  class  Ceshi{
public static void main(String args[])throws Exception{
Class<?> cls = Class.forName("sai.xuexi.person");
Method md [] =cls .getMethods();
for (int x =0; x<md.length; x++){
System.out.print(md[x]);
}
}
}


//取得一个类里面的特定方法
class Person {
private String name;
public void setName(String name) {
this.name= name;
}
public String getName() {
return name;
}
}
public  class  Ceshi{
public static void main(String args[])throws Exception{
Class<?> cls = Class.forName("sai.xuexi.person");//取得class对象
Object obj = cls.newInstance(); //实例化对象,没有像person转型
String attribute ="name" //要调用类之中的属性
Method setMd = cls.getMethod("set" + initcap(attribute),String.class);//set name
Method getMd =cls.getMethod("get"+ initcap(attribute)); //get Name
setMd.invoke(obj,"zhangsan");//等价于 person对象.setName("zhansan")
System.out.print(getMd.invoke(obj)); //等价于 person对象.getName
}
public static String initcap(String str){
return str.substring(0,1).toUpperCase().concat(str.substring(1));
}
}


3调用成员

类之中最后一个组成部分就是成员(Field,也就是属性)

//取得本类的全部成员:
public Field[] getDeclaredFields() throws SecurityException;
//应用
class Person {
private String name;
}
public class Ceshi {
public static void main(String[] args) throws Exception {
Class<?> cls = Class.forName("cn.mldn.demo.Person") ; // 取得Class对象
Field field [] = cls.getDeclaredFields() ; // 取得全部属性
for(int x = 0; x < field.length; x++) {
System.out.println(field[x]);
}
}
}

// 取得指定的成员:
public Field getDeclaredField(String name) throws NoSuchFieldException, SecurityException;
//应用
class Person {
private String name;
}
public class Sai {
public static void main(String[] args) throws Exception {
Class<?> cls = Class.forName("cn.mldn.demo.Person"); // 取得Class对象
Object obj = cls.newInstance(); // 对象实例化属性才会分配空间
Field nameField = cls.getDeclaredField("name") ; // 找到name属性
nameField.setAccessible(true) ; // 解除封装了
nameField.set(obj, "张三") ; // Person对象.name = "张三"
System.out.println(nameField.get(obj)); // Person对象.name




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