您的位置:首页 > 其它

反射相关知识点小结

2015-08-30 17:02 567 查看
(一)知识框架

1.类的加载

当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化

加载

就是指将class文件读入内存,并为之创建一个Class对象.任何类被使用时系统都会建立一个Class对象

连接:接阶段又可以分为三个子步骤:验证,准备和解析

验证:是否有正确的内部结构,确保java类型数据格式的正确性,并适于JVM使用

准备:负责为类的静态成员分配内存,并设置默认初始化值

解析:解析过程就是在类型的常量池中寻找类,接口,字段和方法的符号引用,把这些符号引用替换成直接引

用.这个阶段可以被推迟到初始化之后,当程序运行的过程中真正使用某个符号引用的时候再去解析它

类初始化时机

1)创建类的实例

2)访问类的静态变量,或者为静态变量赋值

3)调用类的静态方法

4)使用反射方式来强制创建某个类或接口对应的java.lang.Class对象

5)初始化某个类的子类

6)直接使用java.exe命令来运行某个主类

2.类加载器

含义:负责将.class文件加载到内在中,并为之生成对应的Class对象

类加载器的组成及作用

Bootstrap ClassLoader 根类加载器:也被称为引导类加载器,负责Java核心类的加载.比如System,String等.在JDK中JRE的lib目录下rt.jar文件中

Extension ClassLoader 扩展类加载器:负责JRE的扩展目录中jar包的加载.在JDK中JRE的lib目录下ext目录

Sysetm ClassLoader 系统类加载器:负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径

二.反射

1.概述

反射机制:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法.对于任意一个对象,都能够调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制

反射技术:其实就是动态加载一个指定的类,并获取该类中的所有的内容,而且将字节码文件封装成对象,并将字节码文件中的内容都封装成对象,这样便于操作这些成员.简单说:反射技术可以对一个类进行解剖

反射的好处:大大的增强了程序的扩展性

2.反射的基本步骤:

获得Class对象,就是获取到指定的名称的字节码文件对象.

实例化对象,获得类的属性.方法或构造函数

访问属性,调用方法,调用构造函数创建对象

3.获取Class对象的三种方式:

每一个类对象都有一个静态的属性class,弊端:必须要先明确该类.如果是明确地获得某个类的Class对象可以用此方式,主要用于传参

Class clazz = Person.class;

通过每个对象都具备的方法getClass来获取.弊端:必须要创建该类对象,才可以调用getClass方法.如果拿到了对象,不知道是什么类型可以用此方式,用于获得对象的类型

Object obj = new Person();

Class clazz1 = obj.getClass();

使用的Class类中的方法,静态的forName方法.指定什么类名(完整的类名),就获取什么类字节码文件对象,这种方式的扩展性最强,只要将类名的字符串传入即可,用于类加载

String classname = “cn.itcast.reflect.Person”;

Class clazz = Class.forName(classname);//当类的字节码已经加载进了内存,就将该字节码返回;如果jvm还没有该字节码,就用类加载器加载,再返回加载的字节码

前两种方式不利于程序的扩展,因为都需要在程序使用具体的类来完成

(二)相关代码实现

JDKNEWS

package cn.itcast_01;

public class DirectionDemo {

public static void main(String[] args) {

Direction d = Direction.FRONT;

System.out.println(d); // cn.itcast_01.Direction@175078b

System.out.println("------------------------------------");

Direction2 d2 = Direction2.FRONT;

System.out.println(d2);// cn.itcast_01.Direction2@11563ff

System.out.println(d2.getName());

d2 = Direction2.RIGHT;

System.out.println(d2);

System.out.println(d2.getName());

System.out.println("------------------------------------");

Direction3 d3 = Direction3.FRONT;

System.out.println(d3);

System.out.println(d3.getName());

d3.show();

d3 = Direction3.LEFT;

System.out.println(d3);

System.out.println(d3.getName());

d3.show();

}

}

package cn.itcast_01;

public class Direction2 {

// 创建几个实例

public static final Direction2 FRONT = new Direction2("前");

public static final Direction2 BEHIND = new Direction2("后");

public static final Direction2 LEFT = new Direction2("左");

public static final Direction2 RIGHT = new Direction2("右");

// 构造私有,别人就不能无限的创建了

// private Direction2() {

// }

// 加入成员变量,并去掉无参构造

private String name;

private Direction2(String name) {

this.name = name;

}

public String getName() {

return name;

}

}

package cn.itcast_01;

ublic class Direction {

// 创建几个实例

public static final Direction FRONT = new Direction();

public static final Direction BEHIND = new Direction();

public static final Direction LEFT = new Direction();

public static final Direction RIGHT = new Direction();

// 构造私有,别人就不能无限的创建了

private Direction() {

}

}

pattern

package cn.itcast_01;

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

public class IODemo extends GetTime{

@Override

public void code() {

try {

BufferedInputStream bis = new BufferedInputStream(

new FileInputStream("a.avi"));

BufferedOutputStream bos = new BufferedOutputStream(

new FileOutputStream("b.avi"));

byte[] bys = new byte[1024];

int len = 0;

while ((len = bis.read(bys)) != -1) {

bos.write(bys, 0, len);

}

bos.close();

bis.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

package cn.itcast_01;

public class GetTimeDemo {

public static void main(String[] args) {

// GetTime gt = new GetTime();

// System.out.println(gt.getTime() + "毫秒");

GetTime gt = new ForDemo();

System.out.println(gt.getTime() + "毫秒");

gt = new IODemo();

System.out.println(gt.getTime() + "毫秒");

}

}

package cn.itcast_01;

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

public abstract class GetTime {

// 需求:请给我计算出一段代码的运行时间

public long getTime() {

long start = System.currentTimeMillis();

// for循环

// for (int x = 0; x < 10000; x++) {

// System.out.println(x);

// }

// 视频

// try {

// BufferedInputStream bis = new BufferedInputStream(

// new FileInputStream("a.avi"));

// BufferedOutputStream bos = new BufferedOutputStream(

// new FileOutputStream("b.avi"));

// byte[] bys = new byte[1024];

// int len = 0;

// while ((len = bis.read(bys)) != -1) {

// bos.write(bys, 0, len);

// }

// bos.close();

// bis.close();

// } catch (IOException e) {

// e.printStackTrace();

// }

// 再给我测试一个代码:集合操作的,多线程操作,常用API操作的等等...

code();

long end = System.currentTimeMillis();

return end - start;

}

public abstract void code();

}

package cn.itcast_01;

public class ForDemo extends GetTime {

@Override

public void code() {

for (int x = 0; x < 100000; x++) {

System.out.println(x);

}

}

}

reflect

package cn.itcast.test;

public class Student {

public void love() {

System.out.println("爱生活,爱Java");

}

}

package cn.itcast.test;

public class Teacher {

public void love() {

System.out.println("爱生活,爱青霞");

}

}

package cn.itcast.test;

import java.io.FileReader;

import java.lang.reflect.Constructor;

import java.lang.reflect.Method;

import java.util.Properties;

/*

* 通过配置文件运行类中的方法

*

* 反射:

* 需要有配置文件配合使用。

* 用class.txt代替。

* 并且你知道有两个键。

* className

* methodName

*/

public class Test {

public static void main(String[] args) throws Exception {

// 反射前的做法

// Student s = new Student();

// s.love();

// Teacher t = new Teacher();

// t.love();

// Worker w = new Worker();

// w.love();

// 反射后的做法

// 加载键值对数据

Properties prop = new Properties();

FileReader fr = new FileReader("class.txt");

prop.load(fr);

fr.close();

// 获取数据

String className = prop.getProperty("className");

String methodName = prop.getProperty("methodName");

// 反射

Class c = Class.forName(className);

Constructor con = c.getConstructor();

Object obj = con.newInstance();

// 调用方法

Method m = c.getMethod(methodName);

m.invoke(obj);

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: