java getinstance 反射_JAVA类加载和反射介绍

本文详细介绍了Java中的反射机制,包括类的加载、链接和初始化过程。通过反射,可以在运行时动态创建对象和调用方法。讲解了Class对象的获取方式,如Class.forName()、对象的getClass()和类字面量。还展示了如何通过反射获取类的构造器、成员变量和方法,并提供了示例代码进行演示。最后,讨论了反射在工厂模式中的应用。
摘要由CSDN通过智能技术生成

简单的来说,反射机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息.

反射机制的优点就是可以实现动态创建对象和编译,体现出很大的灵活性,特别是在J2EE的开发中它的灵活性就表现的十分明显。

当程序主动使用某个类时,若该类还没加载到内存中,系统会通过加载,链接,初始化3个操作对类进行初始化。

类字面常量”,class”创建Class对象的引用时,不会自动地初始化该Class对象,准备工作包含3个步骤:

1.加载:由类加载器执行,该步骤查找字节码,并从这些字节码中创建一个Class对象

2.链接:在链接阶段将验证类中的字节码,为静态域分配存储空间,并且如果必需的话,将解析这个类创建的对其他类的所有引用。

3.初始化:如果该类有超类,则对其初始化,执行静态初始化器和静态初始化块

类的初始化时机

1.创建类的实例

2.访问类或接口的静态变量(static final常量除外,static final变量可以)

3.调用类的静态方法

4.反射(Class.forName(packageName.className))

5.初始化类的子类(子类初始化问题:满足主动调用,即访问子类中的静态变量、方法,否则仅父类初始化)

6.java虚拟机启动时被标明为启动类的类

注:加载顺序:启动类的static block最先加载

(父类静态成员、静态代码块—>子类静态成员、静态代码块—>父类实例成员、代码块——>父类构造函数—>子类实例成员、代码块—>子类构造函数)

我们需要明白在JAVA中任何class都要装载在虚拟机上才能运行,而forClass就是装载类用的,这是要和new不一样,要分清楚哦。

A a = (A)Class.forName(“package.A”).newInstance();和 A a = new A;是等价的。

记住一个概念,静态代码是和class绑定的,class装载成功就表示执行了你的静态代码,而且以后不会再走这套静态代码了。

Class.forName(xxx.xx.xx)的作用是要求JVM查找并加载指定的类,也即是说JVM会执行该类的静态代码段。

JAVA中获取Class对象有3种方式:

1.Class.forName()

2.Object.getClass()

3.类字面常量 xx.class

代码例子:

packageReflect;classDemo{//other codes...

}classhello{public static voidmain(String[] args) {

Class> demo1=null;

Class> demo2=null;

Class> demo3=null;try{//一般尽量采用这种形式

demo1=Class.forName("Reflect.Demo");

}catch(Exception e){

e.printStackTrace();

}

demo2=newDemo().getClass();

demo3=Demo.class;

System.out.println("类名称 "+demo1.getName());//Reflect.Demo

System.out.println("类名称 "+demo2.getName());//Reflect.Demo

System.out.println("类名称 "+demo3.getName());//Reflect.Demo

}

}

从Class中获取信息(可以查看Class的API文档了解):

获取类的构造器

首先介绍一下Constructor类,这个类用来封装反射得到的构造器,Class有四个方法来获得Constructor对象

public Constructor>[] getConstructors() 返回类中所有的public构造器集合,默认构造器的下标为0

public Constructor getConstructor(Class>... parameterTypes) 返回指定public构造器,参数为构造器参数类型集合

public Constructor>[] getDeclaredConstructors() 返回类中所有的构造器,包括私有

public Constructor getDeclaredConstructor(Class>... parameterTypes) 返回任意指定的构造器

获取类的成员变量

成员变量用Field类进行封装,主要的方法非常的类似:

public Field getDeclaredField(String name) 获取任意指定名字的成员

public Field[] getDeclaredFields() 获取所有的成员变量

public Field getField(String name) 获取任意public成员变量

public Field[] getFields() 获取所有的public成员变量

获取类的方法

public Method[] getMethods() 获取所有的共有方法的集合

public Method getMethod(String name,Class>... parameterTypes) 获取指定公有方法 参数1:方法名 参数2:参数类型集合

public Method[] getDeclaredMethods() 获取所有的方法

public Method getDeclaredMethod(String name,Class>... parameterTypes) 获取任意指定方法

常用的就这些,知道这些,其他的都好办……

获取基本信息的例子:

import java.lang.reflect.*;import java.lang.annotation.*;//使用2个注释修饰该类

@SuppressWarnings(value="unchecked")

@Deprecatedpublic classClassTest

{//为该类定义一个私有的构造器

privateClassTest(){

}//定义一个有参数的构造器

publicClassTest(String name){

System.out.println("执行有参数的构造器");

}//定义一个无参数的info方法

public voidinfo(){

System.out.println("执行无参数的info方法");

}//定义一个有参数的info方法

public voidinfo(String str){

System.out.println("执行有参数的info方法"

+ ",其实str参数值:" +str);

}//定义一个测试用的内部类

classInner{

}public static void main(String[] args) throwsException{//下面代码可以获取ClassTest对应的Class

Class clazz = ClassTest.class;//获取该Class对象所对应类的全部构造器

Constructor[] ctors =clazz.getDeclaredConstructors();

System.out.println("ClassTest的全部构造器如下:");for(Constructor c : ctors)

{

System.out.println(c);//private ClassTest()//public ClassTest(java.lang.String)

}//获取该Class对象所对应类的全部public构造器

Constructor[] publicCtors =clazz.getConstructors();

System.out.println("ClassTest的全部public构造器如下:");for(Constructor c : publicCtors)

{

System.out.println(c);//public ClassTest(java.lang.String)

}//获取该Class对象所对应类的全部public方法

Method[] mtds =clazz.getMethods();

System.out.println("ClassTest的全部public方法如下:");for(Method md : mtds)

{

System.out.println(md);//public static void ClassTest.main(java.lang.String[]) throws java.lang.Exception//public void ClassTest.info()//public void ClassTest.info(java.lang.String)//public final void java.lang.Object.wait() throws java.lang.InterruptedException//public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException//public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException//public native int java.lang.Object.hashCode()//public final native java.lang.Class java.lang.Object.getClass()//public boolean java.lang.Object.equals(java.lang.Object)//public java.lang.String java.lang.Object.toString()//public final native void java.lang.Object.notify()//public final native void java.lang.Object.notifyAll()

}//获取该Class对象所对应类的指定方法

System.out.println("ClassTest里带一个字符串参数的info方法为:"

+ clazz.getMethod("info" , String.class));//public void ClassTest.info(java.lang.String)//获取该Class对象所对应类的上的全部注释

Annotation[] anns =clazz.getAnnotations();

System.out.println("ClassTest的全部Annotattion如下:");for(Annotation an : anns)

{

System.out.println(an);

}

System.out.println("该Class元素上的@SuppressWarnings注释为:"

+ clazz.getAnnotation(SuppressWarnings.class));//获取该Class对象所对应类的全部内部类

Class>[] inners =clazz.getDeclaredClasses();

System.out.println("ClassTest的全部内部类如下:");for(Class c : inners)

{

System.out.println(c);//class ClassTest$Inner

}//使用Class.forName方法加载ClassTest的Inner内部类

Class inClazz = Class.forName("ClassTest$Inner");//通过getDeclaringClass()访问该类所在的外部类

System.out.println("inClazz对应类的外部类为:" +inClazz.getDeclaringClass());//class ClassTest

System.out.println("ClassTest的包为:" +clazz.getPackage());//null

System.out.println("ClassTest的父类为:" +clazz.getSuperclass());//class java.lang.Object

}

}

通过Class调用其他类中的构造函数 (也可以通过这种方式通过Class创建其他类的对象)

packageReflect;importjava.lang.reflect.Constructor;classPerson{publicPerson() {

}publicPerson(String name){this.name=name;

}public Person(intage){this.age=age;

}public Person(String name, intage) {this.age=age;this.name=name;

}publicString getName() {returnname;

}public intgetAge() {returnage;

}

@OverridepublicString toString(){return "["+this.name+" "+this.age+"]";

}privateString name;private intage;

}classhello{public static voidmain(String[] args) {

Class> demo=null;try{

demo=Class.forName("Reflect.Person");

}catch(Exception e) {

e.printStackTrace();

}

Person per1=null;

Person per2=null;

Person per3=null;

Person per4=null;//取得全部的构造函数

Constructor> cons[]=demo.getConstructors();try{

per1=(Person)cons[0].newInstance();

per2=(Person)cons[1].newInstance("Rollen");

per3=(Person)cons[2].newInstance(20);

per4=(Person)cons[3].newInstance("Rollen",20);

}catch(Exception e){

e.printStackTrace();

}

System.out.println(per1);//[null 0]

System.out.println(per2);//[Rollen 0]

System.out.println(per3);//[null 20]

System.out.println(per4);//[Rollen 20]

}

}

综合例子:packageReflect;interfaceChina{public static final String name="Rollen";public static int age=20;public voidsayChina();public void sayHello(String name, intage);

}class Person implementsChina{publicPerson() {

}publicPerson(String sex){this.sex=sex;

}publicString getSex() {returnsex;

}public voidsetSex(String sex) {this.sex =sex;

}

@Overridepublic voidsayChina(){

System.out.println("hello ,china");

}

@Overridepublic void sayHello(String name, intage){

System.out.println(name+" "+age);

}privateString sex;

}classhello{public static voidmain(String[] args) {

Class> demo=null;try{

demo=Class.forName("Reflect.Person");

}catch(Exception e) {

e.printStackTrace();

}//保存所有的接口

Class> intes[]=demo.getInterfaces();for (int i = 0; i < intes.length; i++) {

System.out.println("实现的接口 "+intes[i].getName());//Reflect.China

}//获得其他类中的全部构造函数

Constructor>cons[]=demo.getConstructors();for (int i = 0; i < cons.length; i++) {

System.out.println("构造方法: "+cons[i]);//public Reflect.Person()

/publicReflect.Person(java.lang.String)

}for (int i = 0; i < cons.length; i++) {

Class> p[]=cons[i].getParameterTypes();

System.out.print("构造方法: ");int mo=cons[i].getModifiers();

System.out.print(Modifier.toString(mo)+" ");

System.out.print(cons[i].getName());

System.out.print("(");for(int j=0;j

System.out.print(p[j].getName()+" arg"+i);if(j

System.out.print(",");

}

}

System.out.println("){}");

}//构造方法: public Reflect.Person(){}//构造方法: public Reflect.Person(java.lang.String arg1){}//通过反射调用其他类中的方法

try{//调用Person类中的sayChina方法

Method method=demo.getMethod("sayChina");

method.invoke(demo.newInstance());//hello ,china//调用Person的sayHello方法

method=demo.getMethod("sayHello", String.class,int.class);

method.invoke(demo.newInstance(),"Rollen",20);//Rollen 20

}catch(Exception e) {

e.printStackTrace();

}

System.out.println("===============本类属性========================");//取得本类的全部属性

Field[] field =demo.getDeclaredFields();for (int i = 0; i < field.length; i++) {//权限修饰符

int mo =field[i].getModifiers();

String priv=Modifier.toString(mo);//属性类型

Class> type =field[i].getType();

System.out.println(priv+ " " + type.getName() + " "

+ field[i].getName() + ";");//private java.lang.String sex;

}

System.out.println("===============实现的接口或者父类的属性========================");//取得实现的接口或者父类的属性

Field[] filed1 =demo.getFields();for (int j = 0; j < filed1.length; j++) {//权限修饰符

int mo =filed1[j].getModifiers();

String priv=Modifier.toString(mo);//属性类型

Class> type =filed1[j].getType();

System.out.println(priv+ " " + type.getName() + " "

+ filed1[j].getName() + ";");

}//public static final java.lang.String name;//public static final int age;

Object obj= null;try{

obj=demo.newInstance();

}catch(Exception e) {

e.printStackTrace();

}//通过反射操作属性

Field field = demo.getDeclaredField("sex");

field.setAccessible(true);

field.set(obj,"男");//通过反射取得并修改数组的信息:

int[] temp={1,2,3,4,5};

Class>demo=temp.getClass().getComponentType();

System.out.println("数组类型: "+demo.getName());//int

System.out.println("数组长度 "+Array.getLength(temp));//5

System.out.println("数组的第一个元素: "+Array.get(temp, 0));//1

Array.set(temp, 0, 100);

System.out.println("修改之后数组第一个元素为: "+Array.get(temp, 0));//100

}

}

将反射用于工厂模式(结合属性文件的工厂模式):

首先创建一个fruit.properties的资源文件,内容为:

apple=Reflect.Apple

orange=Reflect.Orange

主类代码:

packageReflect;import java.io.*;import java.util.*;interfacefruit{public abstract voideat();

}class Apple implementsfruit{public voideat(){

System.out.println("Apple");

}

}class Orange implementsfruit{public voideat(){

System.out.println("Orange");

}

}//操作属性文件类

classinit{public static Properties getPro() throwsFileNotFoundException, IOException{

Properties pro=newProperties();

File f=new File("fruit.properties");if(f.exists()){

pro.load(newFileInputStream(f));

}else{

pro.setProperty("apple", "Reflect.Apple");

pro.setProperty("orange", "Reflect.Orange");

pro.store(new FileOutputStream(f), "FRUIT CLASS");

}returnpro;

}

}classFactory{public staticfruit getInstance(String ClassName){

fruit f=null;try{

f=(fruit)Class.forName(ClassName).newInstance();

}catch(Exception e) {

e.printStackTrace();

}returnf;

}

}classhello{public static void main(String[] a) throwsFileNotFoundException, IOException{

Properties pro=init.getPro();

fruit f=Factory.getInstance(pro.getProperty("apple"));if(f!=null){

f.eat();//Apple

}

}

}

参考:

参考sina博文<>

参考<>第18章

java反射详解 (各个例子写的还是挺不错的)

http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值