您的位置:首页 > 编程语言 > Java开发

Java学习笔记之反射

2015-06-03 09:59 309 查看
反射学习笔记
一、类的加载

1.简介

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

2.加载
是指将xxx.class文件读入内存,并为之创建一个Class对象。

注意:任何类被加载时系统都会建立一个Class对象。
3.连接:

验证 是否有正确的内部结构,并和其他类协调一致

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

解析 将类的二进制数据中的符号引用替换为直接引用

4.类加载器

负责将xxx.class文件加载到内存中,并为之生成对应的Class对象。

5.类加载器的作用

Bootstrap ClassLoader:根类加载器也称为引导类加载器,负责Java核心类的加载。例如System,String等。在JDK中JRE的lib目录下rt.jar文件中,如图1所示。C:\ProgramFiles\Java\jre1.8.0_45\lib



图1
Extension ClassLoader:扩展类加载器。负责JRE的扩展目录中jar包的加载。在JDK中JRE的lib目录下ext目录。如图2所示。

C:\ProgramFiles\Java\jre1.8.0_45\lib\ext



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

二、反射

1.简介

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

2. 获取字节码文件对象的方式

方式1:通过Object类中getClass()方法,返回当前对象所对应的字节码文件对象

方式2:通过类名.class 完成返回一个字节码文件对象

方式3:(推荐使用)通过Class类中的forName()方法完成

public static Class<?> forName(StringclassName)

//className需要使用的是 完整的类名称包名.类名

测试代码:

//自定义类

public
class
Person {
//构造方法
public Person() {
super();
}
}

//测试类

public
class
ReflectDemo {
public
static void
main(String[]
args) throws
ClassNotFoundException {
//方式1:
Person p = new Person();
Class c =
p.getClass();
System.out.println(c);//注意:字节码文件对象就是xxx.class文件
//方式2:
// Integer.class;
// int.class;
// String.class;
// char.class
//所有类型(基本类型和引用类型)都有字节码文件
Class c2 = Person.class;//类名.class返回Class对象。
System.out.println(c2);
//方式3:推荐使用第三种方法
Class c3 = Class.forName("cn.itcast_01_Reflect.Person");//包名.类名
System.out.println(c3);
}
}

输出结果:

class cn.itcast_01_Reflect.Person
class cn.itcast_01_Reflect.Person
classcn.itcast_01_Reflect.Person

说明:class 包名.类名

3.通过反射获取构造方法并创建对象

Class类简介:
Class
类的实例表示正在运行的Java 应用程序中的类和接口

Class类构造方法:无

常用方法:

public Constructor<?>[]getConstructors()//获取的是所有的public修饰的构造方法
public Constructor<T>getConstructor(Class<?>... parameterTypes)//获取的是指定的public修饰的构造方法
publicConstructor<?>[]getDeclaredConstructors()//获取所有的构造方法,包含私有。
publicConstructor<T>getDeclaredConstructor(Class<?>...parameterTypes)//获取指定的构造方法,包含私有。
Constructor类简介:提供关于类的单个构造方法的信息以及对它的访问权限。

注意:在反射中,把构造方法封装成一个类。

构造方法:无

常用方法

public TnewInstance(Object...initargs) //创建对象

AccessibleObject类简介

AccessibleObject 类是 Field、Method 和Constructor 对象的基类。它提供了将反射的对象标记为在使用时取消默认 Java 语言访问控制检查的能力。从JDK1.2开始。

构造方法:

protected AccessibleObject() //构造方法:仅供 Java 虚拟机使用。

常用方法:

public void setAccessible(boolean flag)//取消java中 权限修饰符的检测

测试案例1:通过反射的方式,创建对象

//自定义类

public
class
Person {
public Stringname;
public
int
age;
private Stringaddress;
//构造方法
public Person() {
super();
}
//私有构造方法
private Person(Stringname) {
super();
this.name =name;
}
public Person(Stringname,
intage, String
address) {
super();
this.name =name;
this.age =age;
this.address =address;
}
//没有返回值没有参数的方法
public
void
method1(){
System.out.println("没有返回值没有参数的方法");
}
//没有返回值,有参数的方法
public
void
method2(String name){
System.out.println("没有返回值,有参数的方法 name:"
+ name);
}
//有返回值,没有参数的方法
public
int
method3(){
System.out.println("有返回值,没有参数的方法");
return 12345;
}
//有返回值,有参数的方法
public Stringmethod4(Stringstr){
System.out.println("有返回值,有参数的方法 , str:" +str);
return"day27" +
str;
}
//私有方法
private
void
method5(){
System.out.println("我是私有方法");
}
@Override
public StringtoString() {
return"Person [name=" +
name + ", age=" +
age + ",address="

+
address + "]";
}
}

//测试类

public
class
ReflectDemo {
public
static void
main(String[]
args) throws
ClassNotFoundException,NoSuchMethodException,
SecurityException,InstantiationException,
IllegalAccessException,IllegalArgumentException,
InvocationTargetException{
//通过反射的方式,创建对象
//1、获取Person类的字节码文件对象
Class c = Class.forName("cn.itcast_01_Reflect.Person");
//包名.类名
//2、获取构造方法
//2.1 获取空参构造方法:
Constructor con =
c.getConstructor(null);//获取空参构造方法
//3.1、通过空参数构造方法,创建对象
Object obj =
con.newInstance(null); //父类引用指向子类对象。
System.out.println(obj);
//2.2 获取有参构造方法
Constructor con1 =
c.getConstructor(String.class,int.class, String.class);
//3.2、通过有参数构造方法,创建对象
Object obj1 =
con1.newInstance("小明", 20 ,"北京");
System.out.println(obj1);
}
}

//输出结果

Person[name=null, age=0, address=null]
Person[name=小明,age=20, address=北京]

测试案例2:通过反射的方式,创建对象(获取私有构造函数,创建对象)

//自定义类和测试案例1相同,此处略。

//测试类

public
class
ReflectDemo3 {
public
static void
main(String[]
args) throws
ClassNotFoundException,NoSuchMethodException,
SecurityException, InstantiationException,
IllegalAccessException,IllegalArgumentException,
InvocationTargetException {
//1、获取Person类的字节码文件
Class c = Class.forName("cn.itcast_01_Reflect.Person");
//2、获取私有的构造方法
Constructor con = c.getDeclaredConstructor(String.class);
//System.out.println(con);//打印私有构造方法
//3、取消检查,暴力访问
con.setAccessible(true);
//4、创建对象
Object obj =
con.newInstance("小明");
System.out.println(obj);//打印对象
}
}

输出结果:

Person [name=小明, age=0, address=null]

4. 通过反射获取成员方法并使用

Class类中常用方法

public Method[] getMethods()//获取所有public修饰的普通方法,包含继承的public方法

public Method[] getDeclaredMethods()//获取所有的方法包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。

public Method getMethod(String name,Class<?>... parameterTypes) //获取指定的public修饰的普通方法

public Method getDeclaredMethod(String name, Class<?>... parameterTypes)//获取指定的普通方法包含私有。

Method类中常用方法:

public
Object invoke(Object obj,Object...
args)//执行获取到的方法

暴力访问

method.setAccessible(true);

注意:不建议使用暴力反射,因为他破坏类的封装特性。

5.通过反射获取成员变量并使用

获取所有成员

getFields,getDeclaredFields

获取单个成员

getField,getDeclaredField

修改成员的值

set(Object obj,Object value)

反射常见问题:

什么时候用反射?

当类不确定时,用反射技术

反射作用:

可以获取一个类中所有的属性和成员,不管是共有还是私有。

反射的好处?

大大的提高了程序的可扩展性

反射的缺点:

破坏类的封装特性。

三、动态代理

代理:本来应该自己做的事情,请了别人来做,被请的人就是代理对象

动态代理:在程序运行过程中产生的对象。而程序运行过程中产生对象其实就是反射,所以,动态代理其实就是通过反射来生成一个代理。

四、枚举

Java的枚举是从JDK1.5开始支持的,用的少,一般用类来代替,相当于一个特殊的java类和类的定义几乎一样。

1、枚举类可以有构造方法,但必须是private的,不能new出对象,可以用Enum.valueOf(Class c,String s)方法创建对象

2、枚举是否可以继承类?

不能,所有的枚举都继承自java.lang.Enum类。由于Java不支持多继承,所以枚举对象不能再继承其他类

3、在枚举种,可以使用抽象方法吗?

可以,需要实现抽象方法

4、枚举可以用增强for循环来遍历

5、枚举可以在switch语句中使用

6、枚举可以实现接口

7、可用枚举定义常量,和C语言类似。

五、泛型的擦除:

泛型的约束只在编译器有效,当编译通过后产生了一个.class的字节码文件。该字节码文件中没有泛型。

六、jdk5与jdk7的新特性

JDK5:

自动装箱和自动拆箱,泛型, 增强for循环,静态导入,可变参数,枚举

JDK7:

二进制字面量,数字字面量可以出现下划线,switch语句可以用字符串, 泛型简化, 异常的多个catch合并
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: