1.反射?
反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
2.如何得到类对象
<1>类名.class<2>对象.getClass()
<3>Class.forName("全限定名");
<4>类加载的loadClass("全限定名");
<5>子类.class.getSuperClass();
<6>包装类.class
package com.zking.test;
import org.junit.Test;
import com.zking.entity.Person;
import com.zking.entity.Son;
public class TestReflect {
/**
* 获取类对象
*/
@Test
public void test1(){
try {
//第一种方式:实体类.class
// Class clazz=Person.class;
// System.out.println(clazz);//打印出:class com.zking.entity.Person
//2:对象.getClass()
// Person per=new Person();
// Class clazz=per.getClass();
// System.out.println(clazz);//打印出:class com.zking.entity.Person
//3:Class.forName("全限定名");
// Class clazz=Class.forName("com.zking.entity.Person");
// System.out.println(clazz);//打印出:class com.zking.entity.Person
//4:类加载的loadClass("全限定名");
// ClassLoader cl=Person.class.getClassLoader();
// Class clazz=cl.loadClass("com.zking.entity.Person");
// System.out.println(clazz);//打印出:class com.zking.entity.Person
//5:子类.class.getSuperClass();
// Class clazz=Son.class.getSuperclass();
// System.out.println(clazz);//打印出:class com.zking.entity.Person
//6:获取包装类的类对象 包装类.class
// Class clazz=Integer.class;
// System.out.println(clazz);//打印出:class java.lang.Integer
} catch (Exception e) {
e.printStackTrace();
}
}
}
3.根据类得到类名(全限定名)
c.getName()------------>全限定名c.getSimpleName() ---->类名
c.getPackage()---------->包名
/**
* 根据类对象 获取 类名(全限定名 包名)
*/
@Test
public void test2(){
Class clazz=Person.class;
System.out.println(clazz.getName());//获取全限定名 打印出:com.zking.entity.Person
System.out.println(clazz.getSimpleName());//获取类名(不包括包名) 打印出:Person
System.out.println(clazz.getPackage().getName());//获取包名 打印出:com.zking.entity
}
4.根据类得到类的属性
c.getField("field属性名");属性名:f.getName()
属性修饰符:f.getModifiers()
属性的数据类型:f.getType().getName()
给属性设值:f.set()
得到属性的值:f.get()
得到私有的属性:f.getDeclaredField("属性名");
得到所有的声明的属性 c.getDeclaredFields()
/**
* 根据类对象 获取 类的属性
*/
@Test
public void test3(){
try {
//之前
// Person person=new Person();
// //person.setPid(1);
// Person person2=new Person();
// //person2.setPid(100);
// Class clazz=Person.class;
// Field[] fields=clazz.getFields();//只能获取public修饰的属性
// Field[] fields2=clazz.getDeclaredFields();//获取所有的属性(包括私有)
// for (Field field : fields2) {
// //获取所有属性的属性名
// System.out.println(field.getName());
// }
//
// System.out.println(fields2.length);
// //获取单个属性(获取的public)
// Field field=clazz.getField("pid");
// //给属性设值
// field.setInt(person, 100);
// //获取属性的值
// System.out.println(field.getInt(person));
//
// //获取单个属性(修饰符为private)
// //Field fieldPname=clazz.getField("pname");
// Field fieldPname=clazz.getDeclaredField("color");
// System.out.println(fieldPname);
//
// System.out.println("psex的数据类型为:"+fieldPname.getType().getSimpleName());
// //private 2
// //public 1
// //protected 4
// //默认 0
// //static 8
// //final 16
//
// System.out.println(Modifier.isPublic(25));
//
// System.out.println("color的修饰符为:"+fieldPname.getModifiers());
//
// //设置可以访问
// fieldPname.setAccessible(true);
//
// //给私有的属性设值
// fieldPname.set(person, "admin");
//
// //获取私有属性的值
// System.out.println(fieldPname.get(person));
//
} catch (Exception e) {
e.printStackTrace();
}
}
5.根据类得到类的方法
c.getMethod() c.getDeclaredMethod();
6.根据类得到类的构造方法
/**
* 获取该类所有的构造方法,并执行
*/
@Test
public void test5(){
Class clazz=Person.class;
Constructor constructor[]=clazz.getDeclaredConstructors();
for (Constructor c : constructor) {
System.out.println(c.getModifiers());
Class clazzType[]=c.getParameterTypes();
for (Class cc : clazzType) {
System.out.println(" "+cc.getSimpleName());
}
}
//调用构造方法(使用构造方法进行实例化对象)
try {
//clazz.newInstance();//调用无参构造
//调用有参构造
Constructor constru=clazz.getDeclaredConstructor(Integer.class,String.class,Integer.class);
constru.newInstance(1,"123",2);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 根据类对象 获取 类的所有的方法
*/
@Test
public void test4(){
//获取所有的方法
Class clazz=Person.class;
Method methods[]=clazz.getDeclaredMethods();
System.out.println(methods.length);
for (Method method : methods) {
//获取每个方法的名字
System.out.println(method.getName());
//每个方法的返回值类型
System.out.println(" "+method.getReturnType().getName());
//每个方法的修饰符
System.out.println(" "+method.getModifiers());
//获取每个方法的参数列表
Class[] classType=method.getParameterTypes();
for (Class c : classType) {
System.out.println(" "+c.getSimpleName());
}
}
//调用方法(无参数)
try {
Person person=new Person();
Method method=clazz.getDeclaredMethod("sleep", String.class,String.class);
//设置可访问
method.setAccessible(true);
//执行方法
method.invoke(person, "小飞和小明","小芳");
} catch (Exception e) {
e.printStackTrace();
}
}
7.根据类得到类的实现接口列表
/**
* 获取实现该类的所有接口 及 父类
*/
@Test
public void test6(){
Class clazz=Person.class;
System.out.println(clazz.getSuperclass().getSimpleName());
//实现的接口
Class clazzInterface[]=clazz.getInterfaces();
for (Class c : clazzInterface) {
System.out.println(c.getSimpleName());
}
}
例子(删除实体类后再读取实体类的class文件):
package com.zking.entity;
import java.io.Serializable;
import javax.servlet.http.HttpServlet;
/**
* 例子:
* <1>新建实体类Person
* <2>三个字段:pid pname psex
* <3>要求该类有父类,并且实现多接口
* <4>通过反射得到改类所有的属性和方法,父类和实现接口
* 要求:在控制台打印实体类
*/
public class Person extends HttpServlet implements Serializable,Runnable{
private Integer pid;
private String pname;
private String psex;
//构造方法
public Person() {
}
public Person(Integer pid, String pname, String psex) {
super();
this.pid = pid;
this.pname = pname;
this.psex = psex;
}
//封装
public Integer getPid() {
return pid;
}
public void setPid(Integer pid) {
this.pid = pid;
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
public String getPsex() {
return psex;
}
public void setPsex(String psex) {
this.psex = psex;
}
//方法
public void run() {
// TODO Auto-generated method stub
}
public void eat(){
System.out.println("打印吃的方法");
}
}
package com.zking.diy;
import java.io.FileInputStream;
public class ClassLoaderDIY extends ClassLoader{
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
System.out.println("自定义加载器:"+name);
name=name.replaceAll("\\.", "/");
System.out.println("替换后:"+name);
//截取
int a=name.lastIndexOf("/");
name=name.substring(a+1);
String path="C:\\Users\\Administrator.USER-20170515AI\\Desktop\\"+name+".class";
try {
FileInputStream fis=new FileInputStream(path);
System.out.println(fis.available());
int len=0;
byte[] b=new byte[fis.available()];
len=fis.read(b);
return defineClass(null, b,0,len);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
package com.zking.test;
import org.junit.Test;
import com.zking.diy.ClassLoaderDIY;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
public class TestReflect {
@Test
public void test1() throws IOException{
Map<Integer, String> map=new HashMap<Integer, String>();
map.put(0, "\t");
map.put(1, "public");
map.put(2, "private");
map.put(4, "protected");
map.put(8, "static");
map.put(16, "final");
StringBuffer sb=new StringBuffer();
Class clazz= null;
try {
clazz=Class.forName("com.zking.entity.Person", true, new ClassLoaderDIY());
sb.append("=======================================================\r\n");
} catch (Exception e) {
e.printStackTrace();
}
//拿package+(全限定名 包名);
sb.append("package "+clazz.getName().substring(0, clazz.getName().lastIndexOf("."))+";\r\n\r\n");
//拿导包(实现接口)
Class[] interfaces= clazz.getInterfaces();
for (Class cl: interfaces) {
sb.append("import "+cl.getName()+";\r\n\r\n");
}
//拿导包(父类)
sb.append("import "+clazz.getSuperclass().getName()+";\r\n\r\n");
/**
* public class Person extends HttpServlet implements Serializable,Runnable{
*/
sb.append(map.get(clazz.getModifiers())+" class "+clazz.getSimpleName());//拿public class Person
sb.append(" extends "+clazz.getSuperclass().getSimpleName()+" implements ");//拿extends 父类 implements
//拿实现的接口
int t1=0;
for (Class cl : interfaces) {
t1++;
if(t1==interfaces.length){
sb.append(cl.getSimpleName()+"{\r\n");
}else{
sb.append(cl.getSimpleName()+",");
}
}
/**
* 拿属性
* private int pid;
* private String pname;
* private String psex;
*/
Field[] fields=clazz.getDeclaredFields();//获取所有的属性(包括私有)
for (Field f : fields) {
sb.append("\t");
sb.append(map.get(f.getModifiers())+" ");
sb.append(f.getType().getSimpleName()+" ");
sb.append(f.getName()+";\r\n");
}
/**
*拿构造方法
*/
Constructor[] con=clazz.getDeclaredConstructors();
for (Constructor c : con) {
sb.append("\t");
sb.append(map.get(c.getModifiers())+" ");
sb.append(clazz.getSimpleName()+"(");
//参数params
Class[] params=c.getParameterTypes();
int i=0;
for (Class cc : params) {
i++;
if(i==params.length){
sb.append(cc.getSimpleName()+" 参数"+i);
}else{
sb.append(cc.getSimpleName()+" 参数"+i+",");
}
}
sb.append("){\r\n\r\n\t}\r\n");
}
/**
* 获取所有的方法(封装+方法)
*/
//拿方法
Method[] methods=clazz.getDeclaredMethods();
for (Method m : methods) {
sb.append("\t");
sb.append(map.get(m.getModifiers())+" ");
sb.append(m.getReturnType().getSimpleName()+" ");
sb.append(m.getName()+"(");
//方法参数
//获取方法的参数列表
Class[] params=m.getParameterTypes();
int i=0;
for (Class c : params) {
i++;
if(i==params.length){
sb.append(c.getSimpleName()+" 参数"+i);
}else{
sb.append(c.getSimpleName()+" 参数"+i+",");
}
}
sb.append("){\r\n\r\n\t}\r\n");
}
sb.append("}");
System.out.println(sb);
/**
* 写入文件
*/
// File file=new File("D:\\桌面文件\\桌面\\控制台的打印文本.txt");
File file=new File("YuHuiLing.java");
if(!file.isAbsolute()){
file.createNewFile();
}
try {
FileOutputStream fos=new FileOutputStream(file);
//fos.write(sb.toString().getBytes());
//fos.close();
OutputStreamWriter osw=new OutputStreamWriter(fos);
osw.write(sb.toString());
osw.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//如果WebRoot路径下面没有YuHuiLing.java文件,即按F5刷新一下
}
}