java笔记(5)--反射

来源:互联网 发布:高清电视网络机顶盒 编辑:程序博客网 时间:2024/05/24 07:32
1.为什么要用反射:
若程序运行时接收到外部传入的一个对象,该对象的编译类型是Object,但程序又需要调用该对象运行类型的方法:
(1).若编译和运行类型都知道,使用 instanceof判断后,强转。
(2).编译时根本无法预知该对象属于什么类,程序只能依靠运行时信息来发现对象的真实信息,这时就必须使用反射了。
(3).要是想得到对象真正的类型,就得使用反射。
2.反射最主要的作用是在框架上,强大的功能是以性能为代价!
3.class类和class类的实例:
Java程序中的各个Java类属于同一类事物,描述这类事物的Java类就是Class类。
对比提问:众多的人用一个什么类表示?众多的Java类用一个什么类表示?
人 ? Person
Java类 ? Class
对比提问: Person类代表人,它的实例对象就是张三,李四这样一个个具体的人,Class类代表Java类,它的各个实例对象又分别对应什么呢?
对应各个类在内存中的字节码,例如,Person类的字节码,ArrayList类的字节码,等等;
一个类被类加载器加载到内存中,占用一片存储空间,这个空间里面的内容就是类的字节码,不同的类的字节码是不同的,所以它们在内存中的内容是不同的;
一个类在虚拟机中只有一份字节码;
4.得到Class对象的三种方式:
  (1). 通过类的class属性;
  类.class;
  (2). 使用Class.forName(String className);className表示 一个类的全限定名
  Class clz = Class.forName("java.util.Date");
  此时 clz 就在描述 java.util.Date这个类
  (3). 通过对象的一个 getClass()方法可以搞定
  Class<?> getClass()    返回此 Object 的运行时类。 


5.九个预定义对象:
基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)
 和关键字 void 也表示为 Class 对象。
他们都对应这 class属性;
 (1).他们的包转类都有TYPE常量;  得到的是他们基本类型的字节码;
数据类型(引用、基本)都有class属性;
 (2).具有相同元素类型和维数的数组都共享同一个 Class 对象
和数组的元素个数和元素的值,元素的顺序无关
  6.使用反射来创建对象
(1).
public T newInstance():只能创建非private,无参的构造方法的对象;好比  new 类();
T classInstance.newIntance();
如同用一个带有一个空参数列表的 new 表达式实例化该类。如果该类尚未初始化,则初始化这个类。 
 
 (2).
  1>.先得到一个指定的构造方法,
  2>.调用构造器里的一个方法,
  T newInstance(Object... initargs) 、
initargs表示构造器的需要的实际参数

 

例子1:

package cn.com.java.wwh.www;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.util.Date;
import java.util.Map;


/**
 *@类的作用:练习反射的基本知识点
 *
 *
 *@author 一叶扁舟
 *@version  1.0
 *@创建时间: 2014-2-10  下午9:14:13
 * 
 */


@Deprecated
class A extends Object implements Serializable{

private  A(String ch)
{
System.out.println(ch);

}

public A() {
}

class B{

}
class C{

}
}
enum Gender{
MAN,WOMAN(),NONE{}
}
public class Test {


/**
* @param args
* @throws Exception 
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub


Class<?> dateTest = new Date().getClass();
Class<?> d1 = Date.class;
System.out.println(d1 == dateTest);
System.out.println(dateTest);
System.out.println("方法一:");
System.out.println("---->"+A.class.toString());
// 权限定名:包名+类名
String className = "cn.com.java.wwh.www.A";
Class<?> cla1 = Class.forName(className);
System.out.println(cla1);
// 通过对象的调用,从而获得class
Object testA = new A();
System.out.println("采用对象获得对象"+testA.getClass());
// public Annotation[] getAnnotations()
// System.out.println(((Class<?>) testA).getAnnotations());
// 针对枚举类型的处理:
System.out.println("Gender.MAN.getClass()----->"+Gender.MAN.getClass());
System.out.println("Gender.WOMAN.getClass()----->"+Gender.WOMAN.getClass());
System.out.println("Gender.NONE.getClass()----->"+Gender.NONE.getClass());
System.out.println("Gender.MAN.getClass()----->"+Gender.MAN.getDeclaringClass());
System.out.println(Map.class);

// 九个预定义Class对象-----------------------------------
int[] arry1 = {1,2};
Class<?> arr1 = arry1.getClass(); 
int[] arry2 = {1,3,5,4};
Class<?> arr2 = arry2.getClass();
System.out.println(arry1 == arry2);
System.out.print("arr1 == arr2------->");
System.out.println(arr1 == arr2);//true
int [][] arry3 = {};
Class<?> arr3 = arry3.getClass();
System.out.print("arr1 == arr3------->");
System.out.println(arr1 == arr3);//false
// 得到数组的Class对象的另外一种方式:
System.out.println(int[][].class.toString());//class [[I
/**
* 基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)
* 和关键字 void 也表示为 Class 对象。
他们都对应这 class属性;
他们的包转类都有TYPE常量;  得到的是他们基本类型的字节码;
数据类型(引用、基本)都有class属性;
*/
// Integer和int表示不同的数据类型
System.out.println(int.class);//int
System.out.println(Integer.TYPE);//int
System.out.println(int.class == Integer.class);//flase
System.out.println(Integer.TYPE == int.class );//true
System.out.println(Integer.TYPE == Integer.TYPE);//true
System.out.println(Integer.TYPE == Integer.class);//false


// Class中的方法=----------------------->
Class<?>  tA = A.class;
System.out.println(tA);
/**
*  Annotation[] getAnnotations()  返回此元素上存在的所有注释。 
*/

System.out.println(tA.getAnnotations().length);


/**
*  Class<?>[] getClasses() 
  得到Class所描述类的所有的public修饰的内部类
 
  Class<?> getDeclaredClasses()
  得到Class所描述类的所有的内部类,和访问权限无关
*/


Class<?>[] innerClass1 = tA.getClasses();
System.out.println("innerClass的 长度是:"+innerClass1.length);
for(Class<?>  inner :innerClass1)
{
System.out.println(inner.toString());
}
Class<?>[] innerClass2 = tA.getDeclaredClasses(); 
System.out.println("输出与访问权限无关的内部类:");
System.out.println(innerClass2.length);
for(Class<?> inner: innerClass2)
{
System.out.println(inner.toString());
}
/**
* Class<?>[] getInterfaces()   确定此对象所表示的类或接口实现的接口。 
*/
Class<?>[] getInterfa = tA.getInterfaces();
System.out.println("tA所实现的所有的接口:");
for(Class<?> inter: getInterfa)
{
System.out.println(inter.toString());
}
/** public Constructor<T> getConstructor(Class<?>... parameterTypes)
               throws NoSuchMethodException,
                      SecurityException
    **/
Constructor<?>[]  construc = tA.getConstructors(); 
for(Constructor  con : construc)
{
System.out.println(con.toString());
}



}


}


例子2:

package cn.com.java.wwh.www;
import java.lang.reflect.Constructor;
import java.util.Date;
/**
 *@类的作用:用反射创建对象
 *
 *@author 一叶扁舟
 *@version  1.0
 *@创建时间: 2014-2-11  下午8:24:53
 * 
 */
class Teacher{


private Teacher(String name){
System.out.println(name);
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "老师你好!";
}

}
public class NewInstanceDemo {
public static void main(String[] args) throws Exception {
// Teacher teacher = new Teacher();
// System.out.println(teacher);


Class<Teacher> teacher1 = Teacher.class;
// Teacher teacher2  = teacher1.newInstance();
// System.out.println(teacher2);
System.out.println("-------------------------------->");
// 反射的第二种方法:
Class<Teacher> teacher3 = Teacher.class;
Constructor<Teacher> teacher4 = teacher3.getDeclaredConstructor(String.class);
// 访问私有的前,先设置可以访问的
teacher4.setAccessible(true);
// 构造对象
Teacher teacher5 = teacher4.newInstance("一叶扁舟");
System.out.println(teacher5);
createInstance();


}
// 创建java.util.Date对象
public static void createInstance() throws Exception
{
// new Date();
String className = "java.util.Date";
Class<?> dateClass = Class.forName(className);
Date date  = (Date)dateClass.newInstance();
System.out.println(date);
// 构造器,无参数
Constructor<Date> date1 = (Constructor<Date>) dateClass.getConstructor();
System.out.println(date1.newInstance());

//   带有参数
Constructor<Date> date2 = 
(Constructor<Date>) dateClass.getConstructor(long.class);
System.out.println(date2.newInstance(10));

}

}

1 0