Tinking in java 琐碎知识点之反射
2014-04-29 21:38
218 查看
25、创建并使用自己的类加载器
JVM中除了根加载器之外都是ClassLoader子类的实例,程序员可以通过扩展(extends)ClassLoader子类并重写它的方法来实现自定义的类加载器。
通过Class对象获取对应类的详细信息
26、使用反射生成并操作对象
Class对象可以获得的该类里的成分包括方法(由Method对象表示)、构造器(由Constructor对象表示)、Field(由field对象表示),这三个类都定义在java.lang.reflect包下。程序可以通过Method对象来执行对应的方法,通过Constructor对象来调用对应的构造器创建对象,能通过Field对象来直接访问并修改对象的属性值。
每个类加载之后,系统会为该类生成一个Class对象,通过Class对象就可以访问到JVM中的这个类了,Java中通常有三种方式获得Class对象:
Class.forName():使用Class类的static方法forName("XXX")
Person.class:调用某个类的class属性来获取该类对应的Class对象。
调用某个对象的getClass()方法,该方法是java.lang.Object类中的一个方法,它返回该对象所属类对应的Class对象
27、通过反射访问属性值
28、泛型与反射
JVM中除了根加载器之外都是ClassLoader子类的实例,程序员可以通过扩展(extends)ClassLoader子类并重写它的方法来实现自定义的类加载器。
通过Class对象获取对应类的详细信息
public class ClassTest { private ClassTest(){ } public ClassTest(String s){ System.out.println("有参构造器"); } public void info(){ System.out.println("无参方法"); } public void info(String s){ System.out.println("有参方法,参数为:"+s); } static class Inner{ static{ System.out.println("Inner被加载"); } } public static void main(String[] args) throws Exception { Class<ClassTest> clazz=ClassTest.class; Constructor[] costors=clazz.getConstructors(); System.out.println("Class对象所对应类的全部public构造器"); for(Constructor c:costors){ System.out.println(c); } Constructor[] allcostors=clazz.getDeclaredConstructors(); System.out.println("Class对象所对应类的全部构造器"); for(Constructor c:allcostors){ System.out.println(c); } Method mtds[]=clazz.getDeclaredMethods(); System.out.println("Class对象所对应类的全部方法"); for(Method c:mtds){ System.out.println(c); } Class inClazz=Class.forName("ClassTest$Inner"); System.out.print("inClazz对应的外部类:"+inClazz.getDeclaringClass()); } }
26、使用反射生成并操作对象
Class对象可以获得的该类里的成分包括方法(由Method对象表示)、构造器(由Constructor对象表示)、Field(由field对象表示),这三个类都定义在java.lang.reflect包下。程序可以通过Method对象来执行对应的方法,通过Constructor对象来调用对应的构造器创建对象,能通过Field对象来直接访问并修改对象的属性值。
每个类加载之后,系统会为该类生成一个Class对象,通过Class对象就可以访问到JVM中的这个类了,Java中通常有三种方式获得Class对象:
Class.forName():使用Class类的static方法forName("XXX")
Person.class:调用某个类的class属性来获取该类对应的Class对象。
调用某个对象的getClass()方法,该方法是java.lang.Object类中的一个方法,它返回该对象所属类对应的Class对象
例程: import java.io.FileInputStream; import java.util.*; public class ObjectPoolFactory { //定义一个对象池,前面是对象名,后面是实际对象 private Map<String,Object> objectPool=new HashMap<String,Object>(); //定义一个创建对象的方法,该方法只要传入一个字符串类名,程序就可以根据类名来生成java对象 private Object creatObjet(String clazzName) throws ClassNotFoundException, InstantiationException, IllegalAccessException{ Class<?> clazz=Class.forName(clazzName);//使用反射来创建某个类或接口对应的java.lang.Class对象 return clazz.newInstance(); } //该方法根据指定文件来初始化对象池,它会根据配置文件来创建对象 public void initPool(String fileName){ FileInputStream fis=null; try { fis=new FileInputStream(fileName); Properties prop=new Properties(); prop.load(fis); System.out.println("prop.stringPropertyNames():"+prop.stringPropertyNames()); for(String name:prop.stringPropertyNames()){ objectPool.put(name, creatObjet(prop.getProperty(name))); } } catch (Exception e) { System.out.println("读取"+fileName+"异常!"); } finally{ try { if(fis!=null){ fis.close(); } } catch (Exception e2) { e2.printStackTrace(); } } } //从object中取出指定name对应的对象 public Object getObject(String name){ return objectPool.get(name); } public static void main(String[] args) { ObjectPoolFactory ofy=new ObjectPoolFactory(); ofy.initPool("obj.txt"); System.out.println(ofy.getObject("a")); System.out.println(ofy.getObject("c")); } } /*输出 prop.stringPropertyNames():[b, a, c] Mon Apr 28 22:15:50 CST 2014 [] */ 配置文件obj.txt a=java.util.Date b=javax.swing.JFrame c=java.util.ArrayList 加强版的 ObjectPoolFactory例程(可以使用方法来改变属性值) 配置文件改为extObj.txt a=javax.swing.JFrame b=javax.swing.JLabel #set the title of a a%title=Test Title import java.io.FileInputStream; import java.lang.reflect.*; import java.util.*; public class ExtendObjectPoolFactory { //定义一个对象池,前面是对象名,后面是实际对象 private Map<String,Object> objectPool=new HashMap<String,Object>(); //定义一个创建对象的方法,该方法只要传入一个字符串类名,程序就可以根据类名来生成java对象 private Object creatObjet(String clazzName) throws ClassNotFoundException, InstantiationException, IllegalAccessException{ Class<?> clazz=Class.forName(clazzName); return clazz.newInstance(); } private Properties config=new Properties(); //该方法根据指定文件来初始化对象池,它会根据配置文件来创建对象 public void initPool(String fileName){ FileInputStream fis=null; try { fis=new FileInputStream(fileName); config.load(fis); //System.out.println("prop.stringPropertyNames():"+prop.stringPropertyNames()); //对于每取出的属性名、属性值对,如果属性名中不包含%,就根据属性值创建一个对象,并将对象放入对象池中 for(String name:config.stringPropertyNames()){ if(!name.contains("%")){ objectPool.put(name, creatObjet(config.getProperty(name))); } } } catch (Exception e) { System.out.println("读取"+fileName+"异常!"); } finally{ try { if(fis!=null){ fis.close(); } } catch (Exception e2) { e2.printStackTrace(); } } } //每取出一对属性名-属性值对,如果属性名中包含百分号(%),即可认为该属性是用于为对象设置属性值 //程序将调用对应的setter方法来为对应的属性设置属性值 public void initPropertyByMethodReflect() throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException{ for(String name:config.stringPropertyNames()){ if(name.contains("%")){ String[] keyAndValue=name.split("%"); Object target=getObject(keyAndValue[0]); //String mtdName="set"+keyAndValue[1].substring(0,1).toUpperCase()+keyAndValue[1].substring(1); String mtdName="setTitle";//与上面的语句功能相同 //通过对象的getClass方法获取他的实现类对应的Class对象 Class<?> clazz=target.getClass(); Method mtd=clazz.getMethod(mtdName,String.class); mtd.invoke(target, config.getProperty(name)); } } } //从object中取出指定name对应的对象 public Object getObject(String name){ return objectPool.get(name); } public static void main(String[] args) throws Exception { ExtendObjectPoolFactory ofy=new ExtendObjectPoolFactory(); ofy.initPool("extObj.txt"); ofy.initPropertyByMethodReflect(); System.out.println(ofy.getObject("a")); } }
27、通过反射访问属性值
import java.lang.reflect.*; import static java.lang.System.*; public class FieldTest { public static void main(String[] args) throws Exception { Person p=new Person(); Class<Person> personClass=Person.class; // 使用getDeclaredField方法获取各种控制符的field Field namefield=personClass.getDeclaredField("name"); //设置通过反射来访问Field时取消访问权限检查 namefield.setAccessible(true); namefield.set(p, "zpc周"); Field agefield=personClass.getDeclaredField("age"); agefield.setAccessible(true); agefield.set(p, 22); out.println(p); } } class Person{ private String name; private int age; public String toString(){ return "Person[name="+name+",age="+age+"]"; } } //输出:Person[name=zpc周,age=0]
28、泛型与反射
import java.util.Date; import javax.swing.JFrame; public class ReflectAndGeneric { public static <T> T getInstance(Class<T> cls){ try { return cls.newInstance(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } } public static void main(String[] args) { Date d=ReflectAndGeneric.getInstance(Date.class); JFrame jfm=ReflectAndGeneric.getInstance(JFrame.class); } }
相关文章推荐
- Tinking in java 琐碎知识点之集合(容器)
- Java基础--反射机制的知识点梳理
- java中的反射机制及其它知识点
- Java中反射的知识点
- java反射知识点总结
- java学习日记(10)———java重要知识点反射的学习
- [think in java]知识点学习
- Thinking in java 琐碎知识点之 I/O流 、对象序列化
- 32点关于Java的琐碎知识点
- Java反射知识点整理
- Java基础之反射知识点总结
- java知识点汇总之七反射
- [think in java]知识点学习
- JAVA反射知识点精解!
- Java基础之反射知识点总结
- 黑马程序员---Java高新技术反射知识点总结
- java反射知识点总结
- 跟着刚哥梳理java知识点——反射和代理(十七)
- java 反射,注解,泛型,内省(高级知识点)
- 疯狂java讲义 琐碎知识点