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

java的反射机制

2016-11-24 21:15 507 查看

java的反射机制

动态的访问某个类的方法,属性,创建对象。(只有在程序执行到某个特定的点的时候,才知道具体的方法,属性,对象是什么)。

1.1 java反射的API

1.1 java反射的API



1.2 Class类的作用

Class 类的实例表示正在运行的 Java 应用程序中的类和接口

Class类的实例表示的是内存中某个类或者接口对应的class文件。

File file=new File(“1.txt”);

package com.bjsxt.clz;

public class TestClass {

public static void main(String[] args) {

try {
//1获得Class的实例
//方式一:通过Calss提供的forName的静态方法,传入是一个类完全限定名
/***
* 首先查看内存是否存在指定完全限定名对应的类的class文件,如果有直接返回对应的Class的对象
* 如果没有,将该类加载进内存,返回Class的对象,如果指定的完全限定名不能加载对应的class文件
* 抛出异常
* ***/
Class clz=Class.forName("java.lang.String");
System.out.println(clz.getName());
//方式二:通过类名获得对应的Class实例
Class clz2=String.class;
//方式三:通过对象调用getClass获得
String str="abc";
Class clz3=str.getClass();

//Class的实例提供的方法

ClassLoader clzLoader1=clz.getClassLoader();

//获得Student类对应的class文件
Class clz4=Student.class;
ClassLoader clzLoader2=clz4.getClassLoader();

Class clz5=Pet.class;
ClassLoader clzLoader3=clz5.getClassLoader()
/**
* 所有classpath目录下的类都有AppClassLoader加载,而且所有自定类的加载是一样的。
* ***/
System.out.println(clzLoader1+"\t"+clzLoader2+"\t"+clzLoader3);

//创建此 Class 对象所表示的类的一个新实例:本次创建对象,调用的是某个类的无参数构造方法
Object s=clz4.newInstance();
Object p=clz5.newInstance();
System.out.println(s instanceof Student);
System.out.println(p instanceof Pet);

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

public void method(Class clz){
//创建任意类的对象
//clz.newInstance();
}
}


1.3 Method类的作用

Method:封装的是类或接口上单独某个方法

package com.bjsxt.method;

import java.lang.reflect.Method;

public class TestMethod {

public static void main(String[] args) {

try {
//1 获得Class的对象
Class clz=Class.forName("com.bjsxt.method.Student");
//2获得Student中的所有公共方法包含父类中的
Method[] methods=clz.getMethods();
for(Method m:methods){
System.out.println(m);
}

//获得本类中声明的方法
Method[] meths=clz.getDeclaredMethods();
for(Method m:meths){
System.out.println("==="+m);
}

//获得某个指定方法名和参数类型的方法
Method method=clz.getDeclaredMethod("intro", String.class);
System.out.println("---"+method);

//3Method对象提供的方法
String methodName=method.getName();//方法名
int m=method.getModifiers();//权限
Class clz1=method.getReturnType();//返回值类型
System.out.println(methodName+"\t"+m+"\t"+clz1);

//Student s =new .....

Object student=clz.newInstance();
//完成method表示的某个方法的调用
method.invoke(student, "小强");  //student.intro("小强")
//obj.method(args);

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}


1.4 Constructor的作用

Constructor 完成Class实例 所表示的类的构造方法的封装

package com.bjsxt.cons;

import java.lang.reflect.Constructor;

import com.bjsxt.method.Student;

public class TestConstructor {

public static void main(String[] args) {

//1获得Class对象
Class clz=Student.class;
//2获得clz表示的类的构造方法

//获得所有构造方法
Constructor[] cons=clz.getConstructors();

for(Constructor c:cons){
System.out.println(c);
}
//获得某个特定的构造方法

try {
Constructor conDefault=clz.getConstructor();
System.out.println("=="+conDefault);

//通过默认的无参数构造方法,创建对象
Object obj=conDefault.newInstance();
System.out.println(obj instanceof Student);

//获得带参数的构造方法
Constructor conArgs=clz.getConstructor(String.class,Integer.class);
Object obj2=
4000
conArgs.newInstance("小强",120);
System.out.println(obj2);

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}


1.5 Field类的作用

Field 封装的是Class对象表示的类的所有属性

package com.bjsxt.field;

import java.lang.reflect.Field;

import com.bjsxt.method.Student;

public class TestField {

public static void main(String[] args) {
//1获得Class对象
Class clz=Student.class;

//获得clz表示的类中的所有属性
Field[] fls=clz.getDeclaredFields();
for(Field f:fls){
System.out.println(f);
}

try {
//获得指定名称的一个属性
Field f=clz.getDeclaredField("age");
System.out.println("----"+f);
//其他方法
System.out.println(f.getName());
System.out.println(f.getModifiers());
System.out.println(f.getType());

f.setAccessible(true);

//给特定属性赋值和取值
Object obj = clz.newInstance();
f.set(obj, 1000); //obj.xxx(1000);
//获得某个属性的值
Object x=f.get(obj);
System.out.println("==="+x);
}catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}


1.5 练习

通过反射创建对象,访问对象的属性,方法

package com.bjsxt.demo;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import com.bjsxt.clz.Pet;
import com.bjsxt.method.Student;

public class TestDemo {

/***
* 通过反射创建对象,访问对象的属性,方法
* **/
public static void main(String[] args) {

//获得Class对象ss
//Class clz = Student.class;
Class clz = Pet.class;
Object obj=getInstance(clz);
System.out.println("------"+obj);
}

private static Object getInstance(Class clz) {
Object obj=null;
try {

//创建clz表示的类的对象
obj=clz.newInstance();
//获得所有属性
Field[] fls = clz.getDeclaredFields();
for(Field f:fls){
//获得每个字段的名称
String fname=f.getName();
//System.out.println(fname);
fname=fname.toLowerCase();
//获得某个属性对应set方法的方法名
String setMethod="set"+fname.substring(0, 1).toUpperCase()+fname.substring(1);
//获得某个属性对应get方法的方法名
String getMethod="get"+fname.substring(0, 1).toUpperCase()+fname.substring(1);

Class type=f.getType();//获得属性对应的类型
System.out.println("type="+type);

//获得属性对应的setMethod方法
Method set=clz.getDeclaredMethod(setMethod, type);
if(type.equals(String.class)){
set.invoke(obj, "乌龟");
}else if(type.equals(Integer.class)){
set.invoke(obj, 1000);
}

}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}

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