关于Java基础的文章,我觉得写得还可以,以前发在了我其它的博客了,肯定是原创,现在再分享给大家出来。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
在总结java基础的博客里有简单的写到反射,这里再来深入的理解。http://blog.csdn.net/jin870132690/article/details/41958937
首先的问题是什么是反射?百度百科给出的定义是这样的:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;
这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
用我自己的话简而言之就是,程序运行时能操纵类的各种成分。
java是完全面向对象的语言,在java中万物皆对象,比如男人和女人都可以属于Person类,那么众多的java类是不是也可以用一个类表示呢?
在java中就用一个名为Class的类来表示。
a,类名.class
b,对象.getClass()
c,Class.forName("类名")
<div style="text-align: left;">	public static void main(String[] args) throws ClassNotFoundException {</div>		Date d = new Date();
		System.out.println(Date.class);\\a,类名.class 
<div style="text-align: left;">		System.out.println(Class.forName("java.util.Date"));\\c,Class.forName("类名")</div>		System.out.println(d.getClass());\\b,对象.getClass()
<div style="text-align: left;">	}</div>
Constructor类代表某类中的一个构造方法。
Class clazz = Class.forName("java.lang.String");
Constructor con = clazz.getConstructor(byte[].class);//得到某一个构造函数
Constructor[] cons = clazz.getConstructors();//得到全部构造函数
使用Constructor.newInstance()方法
<div style="text-align: left;">//a,获取class类</div><div style="text-align: left;">		Class clazz = Class.forName("jinfulin.b.bean");  </div>		//b,获取Gonstructor构造方法
<div style="text-align: left;">		Constructor cons = clazz.getConstructor(String.class,int.class);  </div>		//c,调用newInstance()方法.
<div style="text-align: left;">        Object obj = cons.newInstance("sf",21);  </div>
<div style="text-align: left;">  Class clazz = Class.forName("jinfulin.p.bean.Person");  </div><div style="text-align: left;">        Object obj = clazz.newInstance();//创建一个新的无参的实例  </div>
Field getField(String s);//只能获取公有和父类中公有
Field getDeclaredField(String s);//获取该类中所有的成员变量,包括私有
setAccessible(true);//对私有字段的访问取消权限检查。暴力访问。
<div style="text-align: left;">		//获取字段(属性)</div><div style="text-align: left;">		PointDemo pd = new PointDemo(3,2);</div><div style="text-align: left;">		Field field1 = pd.getClass().getField("x");</div>		Object o1 = field1.get(pd);
<div style="text-align: left;">		System.out.println(o1);</div>//		field1.set(o1, 12);
		
<div style="text-align: left;">		Field field2 = cls2.getDeclaredField("y");</div>		Object o2 = cls2.newInstance();
<div style="text-align: left;">//		Constructor con2 = cls2.getConstructor(int.class,int.class);</div>		field2.setAccessible(true);//暴力反射
		field2.set(o2, 12);
<div style="text-align: left;">		System.out.println(field2.get(o2));</div>
-- 运用反射,将PointDemo类中的字符串中的所有字符替b换为a.
<div style="text-align: left;">/**</div><div style="text-align: left;">	 * 运用反射,将PointDemo类中的字符串中的某一个字符替换掉.</div>	 * @throws Exception 
	 */
<div style="text-align: left;">	private static void changeStringValue() throws Exception {</div>		Class cls = Class.forName("cn.jinfulin.day1.Reflect.PointDemo");
<div style="text-align: left;">		for(Field field : fields){</div>		Object obj = cls.newInstance();
		Field[] fields = cls.getFields();
<div style="text-align: left;">				String newString = oldString.replace('b', 'a');</div>			if(field.getType() == String.class){
				String oldString = (String) field.get(obj);
<div style="text-align: left;">	}</div>				field.set(obj, newString);
				
			}
		}
<div style="text-align: left;">		System.out.println(obj);</div>
Method[] getDeclaredMethods();//获取本类中包含私有。
Method getMethod("方法名",参数.class);
Object invoke(Object obj ,参数);//调用方法
如果方法是静态,invoke方法中的对象参数可以为null。
比如
<div style="text-align: left;"><span style="white-space:pre">	</span>public static void main(String[] args) throws Exception {</div><span style="white-space:pre">		</span>
<div style="text-align: left;"><span style="white-space:pre">		</span>Object obj = clazz.newInstance();</div><span style="white-space:pre">		</span>Class clazz = Class.forName("java.util.Date");
<div style="text-align: left;"><span style="white-space:pre">	</span>    Object returnVaule=me.invoke(obj, null);</div><span style="white-space:pre">	</span>    Method me=clazz.getMethod("toString", null);  
<span style="white-space:pre">	</span>    System.out.println(returnVaule);      
<div style="text-align: left;"><span style="white-space:pre">	</span>}    </div>
1)通常方式:str.charAt(1)
2)反射方式:
<div style="text-align: left;"> Method charAtMethod =Class.forName(“java.lang.String”).getMethod(“charAt”,int.class);</div><div style="text-align: left;"> charAtMethod.invoke(str,1);//调用方法</div>
java中main方法的参数是一个数组,比如String [] args
但是由于java要兼容1.4版本,直接调用会将数组打散成单独的参数。
解决办法:
mainMethod.invoke(null,new Object[]{new String[]{"xxx"}});
mainMethod.invoke(null,(Object)new String[]{"xxx"});
<div style="text-align: left;">	public static void main(String[] args) throws Exception {</div>		
		Class clazz = Class.forName("Ceshi.Demo.CeshiDemo");
<div style="text-align: left;">	    Method mainMethod=clazz.getMethod("main", String[].class);  </div>		Object obj = clazz.newInstance();
<div style="text-align: left;">	    System.out.println(returnVaule);      </div>	    Object returnVaule=mainMethod.invoke(obj, (Object)new String[]{});
<div style="text-align: left;">	}</div>
基本数据类型的一维数组可以当做Object类型使用,不能当做Object[]类型使用,
非基本数据类型的一维数组,既可以当做Object类型使用, 又可以当做Object[]使用。
Array工具类用于完成对数组的反射操作。
Array.getLength(Object obj);//获取数组的长度
        Array.get(Object obj,int x);//获取数组中的元素
<div style="text-align: left;">	/**</div><div style="text-align: left;">	 * 数组的反射</div>	 */
<div style="text-align: left;">	private static void printObject(Object obj) {</div>		Class clazz = obj.getClass();
<div style="text-align: left;">			int len = Array.getLength(obj);</div>		if(clazz.isArray()){//如果是数组,就分行打印
<div style="text-align: left;">				System.out.println(Array.get(obj, i));</div>			for (int i = 0; i <len; i++) {
				
			}
		}else{//如果不是就直接打印
<div style="text-align: left;">	}</div>			System.out.println(obj);
<div style="text-align: left;">		}</div>
框架就像房子,而我们写的类就相当于给房子做装修。
 我们在写框架的时候,调用的类还未出现,那么,框架无法知道要被调用的类名,所以在程序中无法直接new其某个类的实例对象,而要用反射来做。
工具类被用户类调用,
而框架是调用用户提供的类。
a,普通方式
FileInputStream in = new FileInputStream("config.properties");
b,类加载器,全写
InputStream in = ReflectTest2.class.getClassLoader().getResourceAsStream("cn/jinfulin/day1/Reflect/config.properties");
c,目录在类文件中,简写(在Java所在文件夹中会自动在类文件夹中创建相同一份)
InputStream in = ReflectTest2.class.getResourceAsStream("config.properties");
d,目录在其它包中,加/回到根目录下在找
InputStream in = ReflectTest2.class.getResourceAsStream("/cn/jinfulin/day1/config/config.properties");
<div style="font-family: Arial; font-size: 14px; line-height: 26px; text-align: left;">package cn.jinfulin.day1.Reflect;</div><span style="font-family:Arial;"><span style="font-size: 14px; line-height: 26px;">
import java.io.InputStream;
</span></span><div style="font-family: Arial; font-size: 14px; line-height: 26px; text-align: left;">import java.util.Properties;</div><span style="font-family:Arial;"><span style="font-size: 14px; line-height: 26px;">import java.util.Collection;
public class ReflectTest2 {
</span></span><div style="font-family: Arial; font-size: 14px; line-height: 26px; text-align: left;">	public static void main(String[] args) throws Exception {</div><span style="font-family:Arial;"><span style="font-size: 14px; line-height: 26px;">	//仿照框架,用反射
		
		//1,读取配置文件中的内容
			//1.1源:键值对配置文件
</span></span><div style="font-family: Arial; font-size: 14px; line-height: 26px; text-align: left;">//		FileInputStream in = new FileInputStream("config.properties");</div><span style="font-family:Arial;"><span style="font-size: 14px; line-height: 26px;">//			//1.2三种得到输入流的方法
		//a,普通方式
//		//b,类加载器,全写
</span></span><div style="font-family: Arial; font-size: 14px; line-height: 26px; text-align: left;">//		InputStream in = ReflectTest2.class.getClassLoader().getResourceAsStream("cn/jinfulin/day1/Reflect/config.properties");</div><span style="font-family:Arial;"><span style="font-size: 14px; line-height: 26px;">		//c,目录在类文件中,简写(在Java所在文件夹中会自动在类文件夹中创建相同一份)
//		InputStream in = ReflectTest2.class.getResourceAsStream("config.properties");
		//d,目录在其它包中,加/回到根目录下在找
</span></span><div style="font-family: Arial; font-size: 14px; line-height: 26px; text-align: left;">		in.close();</div><span style="font-family:Arial;"><span style="font-size: 14px; line-height: 26px;">		InputStream in = ReflectTest2.class.getResourceAsStream("/cn/jinfulin/day1/config/config.properties");
		Properties pros = new Properties();
		pros.load(in);
		String className = pros.getProperty("className");
		System.out.println(className);
</span></span><div style="font-family: Arial; font-size: 14px; line-height: 26px; text-align: left;">		PointDemo pd2 = new PointDemo(5, 5);</div><span style="font-family:Arial;"><span style="font-size: 14px; line-height: 26px;">		//2,读取类文件的字节码
		Class cls1 = Class.forName(className);
		Collection collections = (Collection)cls1.newInstance();
		
		
		
//		Collection collections = new HashSet();
		//3,集合中添加元素
		PointDemo pd1 = new PointDemo(3, 3);
		PointDemo pd3 = new PointDemo(3, 3);
</span></span><div style="font-family: Arial; font-size: 14px; line-height: 26px; text-align: left;">}</div><span style="font-family:Arial;"><span style="font-size: 14px; line-height: 26px;">
		collections.add(pd1);
		collections.add(pd2);
		collections.add(pd3);
		collections.add(pd1);
		pd1.x = 12;
		collections.remove(pd1);
		System.out.println(collections.size());
	}
</span></span><div style="text-align: left;"><span style="font-family:Arial;"><span style="font-size: 14px; line-height: 26px;">
</span></span></div>
以前写过一篇关于反射的文章,为什么又单独的写一遍?因为我觉得反射比较重要,以后学到了框架更是少不了的用,本篇显然比上一篇写反射的文章要深入多了,但是还不够,因为这些东西都是老师讲给我听,我照葫芦画瓢做出来的,像这些复杂的知识,真正掌握要还需要实践中见识更多的变化与应用场景才行。
原文:http://blog.csdn.net/jinfulin/article/details/44967503