java反射机制就是在运行状态中,对于任意一个类(class文件),都能够知道这个类的所有属性和方法
对于任意一个对象,都能够调用它的任意一个方法和属性
这种动态获取信息以及动态调用方法的功能称为java语言的反射机制
package com.monfolld.reflect;
public class Person {
private int age;
private String name;
public Person(int age,String name){
super();
this.age=age;
this.name=name;
System.out.println("Person param run..."+this.name+":"+this.age);
}
public Person(){
super();
System.out.println("person run");
}
public void show(){
System.out.println(name+"...show"+age);
}
private void privateMethod(){
System.out.println("method run");
}
public void paramMethod(String str,int num){
System.out.println("paramMethod run..."+str+":"+num);
}
public static void staticMethod(){
System.out.println("static method run ....");
}
}
package com.monfolld.reflect;
public class ReflectDemo {
public static void main(String[] args)throws ClassNotFoundException{
getClassObject_3();
}
/*方式一:
获取字节码对象的方式
* 1.Object类中的getClass()方法的
* 想要用这种方式,必须要明确具体的类,并穿件对象
*
* */
public static void getClassObject_1(){
Person p=new Person();
Class clazz=p.getClass();
Person p1=new Person();
Class clazz1=p1.getClass();
System.out.println(clazz==clazz1);
}
/*方式二:
* 2.任何数据类型都具备一个静态的属性.class来获取其对应的class对象
* 相对简单,但是还是要明确类,用到类中的静态成员
* 还是不够扩展
* */
private static void getClassObject_2(){
Class clazz=Person.class;
Class clazz1=Person.class;
System.out.println(clazz==clazz1);
}
/*方式三:
* 只要通过给定的字符串名称九合一获取该类,更为拓展
* 可是用Class类中的方法完成
* 该方法就是forName*/
public static void getClassObject_3()throws ClassNotFoundException{
String className="com.monfolld.reflect.Person";
Class clazz= Class.forName(className);
System.out.println(clazz);
}
}
package com.monfolld.reflect;
import java.lang.reflect.Constructor;
public class ReflectDemo2 {
public static void main(String[] args) throws Exception{
createNewObject_2();
}
public static void createNewObject() throws ClassNotFoundException,InstantiationException,IllegalAccessException{
//早起:new时候,先根据被new的类名称寻找该类的字节码文件,并加载进内存,
//并创建该字节码文件对象,并借着创建字节文件的对应Person对象
/* com.monfolld.reflect.Person p=new com.monfolld.reflect.Person();*/
//现在:
String name= "com.monfolld.reflect.Person";
//寻找该名称类文件,并加载进内存,产生class对象
Class clazz=Class.forName(name);
//如何产生该类的对象呢?
Object obj=clazz.newInstance();
}
public static void createNewObject_2() throws Exception{
/*com.monfolld.reflect.Person p=new com.monfolld.reflect.Person(39,"小强");*/
/*当获取指定名称对应类中的所体现的对象时,
* 而该对象初始化不使用空参数构造该怎么办呢?
* 既然是获取指定的构造函数进行对象的初始化
* 所以应该先获取到该构造函数,通过字节码文件对象即可完成
* 该方法是:getConstructor(paramterTypes)*/
String name="com.monfolld.reflect.Person";
Class clazz=Class.forName(name);
//获取到了指定的构造函数对象
Constructor constructor=clazz.getConstructor(int.class,String.class);
//通过该构造器对象的newInstance方法进行对象的初始化
Object obj=constructor.newInstance(39,"小明");
}
}
package com.monfolld.reflect;
import java.lang.reflect.Field;
public class ReflectDemo3 {
public static void main(String[] args)throws Exception{
getFieldDemo();
}
public static void getFieldDemo() throws Exception{
Class clazz=Class.forName("com.monfolld.reflect.Person");
Field field=null;//clazz.getField("age");//只能获取共有的
field=clazz.getDeclaredField("age");//只获取本类,但包含私有
//对私有字段的访问取消权限检查,暴力访问
field.setAccessible(true);
Object obj=clazz.newInstance();//创建对象
//field.set(obj,89);
Object o=field.get(obj);//获取对象返回的值
System.out.println(o);
}
}
package com.monfolld.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class ReflectDemo4 {
public static void main(String[] args)throws Exception{
getMethodDemo_3();
}
public static void getMethodDemo()throws Exception{
Class clazz=Class.forName("com.monfolld.reflect.Person");
Method[] methods=clazz.getMethods();//获取的都是共有方法
methods=clazz.getDeclaredMethods();//只获取本类中的所有方法,包含私有
for(Method method:methods){
System.out.println(method);
}
}
public static void getMethodDemo_2()throws Exception {
Class clazz=Class.forName("com.monfolld.reflect.Person");
Method method=clazz.getMethod("show",null);//获取空参数一般方法
//Object obj=clazz.newInstance();
Constructor constructor=clazz.getConstructor(int.class,String.class);
Object obj=constructor.newInstance(37,"小明");
method.invoke(obj,null);
}
public static void getMethodDemo_3()throws Exception{
Class clazz=Class.forName("com.monfolld.reflect.Person");
Method method=clazz.getMethod("paramMethod", String.class, int.class);
Object obj=clazz.newInstance();
method.invoke(obj,"小强",89);
}
}
反射练习
电脑运行
package com.monfolld.reflect.test;
import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;
/*电脑运行*/
public class ReflectTest {
public static void main(String[] args)throws Exception{
MainBoard mb=new MainBoard();
mb.run();
//每次添加一个设备都需要修改代码传递一个新创建的对象
//mb.usePCI(new SoundCard());
//能不能不修改代码就可以完成这个动作
//不能new来完成,俄日是只获取其class文件。在内部实现创建对象的动作。
File configFile=new File("pci.properties");
Properties prop=new Properties();
FileInputStream fis=new FileInputStream(configFile);
prop.load(fis);
for (int x=0;x<prop.size();x++){
String pciName= prop.getProperty("pci"+(x+1));
Class clazz=Class.forName(pciName);//用class去加载这个pci子类
PCI p=(PCI)clazz.newInstance();
mb.usePCI(p);
}
fis.close();
}
}
主板
package com.monfolld.reflect.test;
public class MainBoard {
public void run(){
System.out.println("main board run...");
}
public void usePCI(PCI p) {//PCI p=new SoundCard();
if (p != null) {
p.open();
p.close();
}
}
}
声卡网卡
package com.monfolld.reflect.test;
public class SoundCard implements PCI {
public void open(){
System.out.println("sound open");
}
public void close(){
System.out.println("sound close");
}
}
package com.monfolld.reflect.test;
public class NetCard implements PCI {
public void open(){
System.out.println("net open");
}
public void close(){
System.out.println("net close");
}
}
接口
package com.monfolld.reflect.test;
public interface PCI {
public void open();
public void close();
}
pci.properties文件
pci1=com.monfolld.reflect.test.SoundCard
pci2=com.monfolld.reflect.test.NetCard