类加载机制和反射
类的加载、连接、初始化
当系统在第一次使用某个类时,加载该类,也可能预加载机制来加载某个类时。
加载 就是指将 class 文件读入内存,并为之创建一个 Class 对象。 任何类被使用时系统都会建立一个 Class 对象
连接 验证 是否有正确的内部结构,并和其他类协调一致 准备 负责为类的静态成员分配内存,并设置默认初始化值 解析 将类的二进制数据中的符号引用替换为直接引用
初始化
类的初始化
类的初始化阶段,虚拟机负责对类进行初始化,主要是对类变量进行初始化,声明类变量时可以给定初始值,或者使用静态初始化块为类变量指定初始化值。
static int a
=5;
static int b
;
static {
b
=9;
}
类加载器
概念:将
.class文件加载到内存中
,并生成相对应的Class对象
分类以及作用
1.根类加载器
2.扩展类加载器
3.系统类加载器
反射
Java中的反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称 为 java 语言的反射机制。
创建一个学生类,以此举例:
public class Student {
public String name
;
int age
;
private double height
;
public Student(String name
, int age
, double height
) {
this.name
= name
;
this.age
= age
;
this.height
= height
;
System
.out
.println("有参构造调用了");
}
public Student() {
System
.out
.println("无参构造调用了");
}
private Student(String name
,int age
){
this.name
=name
;
this.age
=age
;
System
.out
.println("私有构造调用了");
}
public void show(){
System
.out
.println("空参方法");
}
public void show1(int age
){
System
.out
.println(age
);
}
private void show2(String name
,int age
){
System
.out
.println(name
+"=="+age
);
}
@Override
public String
toString() {
return "Student{" +
"name='" + name
+ '\'' +
", age=" + age
+
", height=" + height
+
"," +
'}';
}
}
获取class对象
在Java中获取对象可以用三种方式:
1、
forName(String clazzName
)静态方法,且传入参数为完整包名。
2、调用
class属性来获取对象。
3、
getClass()方法。
三种方法对比,第二种方法代码更安全,性能更好。
从class获取信息
通过反射获取构造方法,并实例化。
public class Demo1 {
public static void main(String
[] args
) throws ClassNotFoundException
, NoSuchMethodException
, IllegalAccessException
, InvocationTargetException
, InstantiationException
{
Class
<?> student
= Class
.forName("com.westore.reflect.Student");
Constructor
<?>[] constructors
= student
.getConstructors();
for (Constructor
<?> constructor
: constructors
) {
System
.out
.println(constructor
);
}
System
.out
.println("===========");
Constructor
<?>[] declaredConstructors
= student
.getDeclaredConstructors();
for (Constructor
<?> declaredConstructor
: declaredConstructors
) {
System
.out
.println(declaredConstructor
);
}
System
.out
.println("==========");
Object o2
= student
.newInstance();
System
.out
.println("==================");
Constructor
<?> constructor
= student
.getConstructor(String
.class, int.class, double.class);
System
.out
.println(constructor
);
Object o1
= constructor
.newInstance("lee",18,178);
System
.out
.println("==============");
Constructor
<?> constructor1
= student
.getDeclaredConstructor(String
.class, int.class);
System
.out
.println(constructor1
);
constructor1
.setAccessible(true);
Object o
= constructor1
.newInstance("LEE",18);
System
.out
.println("===============");
}
}
public com
.westore
.reflect
.Student()
public com
.westore
.reflect
.Student(java
.lang
.String
,int,double)
===========
private com
.westore
.reflect
.Student(java
.lang
.String
,int)
public com
.westore
.reflect
.Student()
public com
.westore
.reflect
.Student(java
.lang
.String
,int,double)
==========
无参构造调用了
==================
public com
.westore
.reflect
.Student(java
.lang
.String
,int,double)
有参构造调用了
==============
private com
.westore
.reflect
.Student(java
.lang
.String
,int)
私有构造调用了
===============
通过反射获取字段,并设置值
public class Demo2 {
public static void main(String
[] args
) throws ClassNotFoundException
, NoSuchFieldException
, IllegalAccessException
, InstantiationException
{
Class
<?> aClass
= Class
.forName("com.westore.reflect.Student");
Object o
= aClass
.newInstance();
Field
[] fields
= aClass
.getFields();
for (Field field
: fields
) {
System
.out
.println(field
);
}
Field
[] declaredFields
= aClass
.getDeclaredFields();
for (Field declaredField
: declaredFields
) {
System
.out
.println(declaredField
);
}
Field age
= aClass
.getDeclaredField("age");
age
.set(o
,23);
System
.out
.println(age
.get(o
));
System
.out
.println(age
);
Field height
= aClass
.getDeclaredField("height");
height
.setAccessible(true);
height
.set(o
,140);
System
.out
.println(height
.get(o
));
}
}
无参构造调用了
public java
.lang
.String com
.westore
.reflect
.Student
.name
====================
public java
.lang
.String com
.westore
.reflect
.Student
.name
int com
.westore
.reflect
.Student
.age
private double com
.westore
.reflect
.Student
.height
protected double com
.westore
.reflect
.Student
.weight
23
int com
.westore
.reflect
.Student
.age
140.0
通过反射获取方法并调用
public class Demo3 {
public static void main(String
[] args
) throws ClassNotFoundException
, NoSuchMethodException
, IllegalAccessException
, InstantiationException
, InvocationTargetException
{
Class
<?> aClass
= Class
.forName("com.westore.reflect.Student");
Object o
= aClass
.newInstance();
Method
[] methods
= aClass
.getMethods();
for (Method method
: methods
) {
System
.out
.println(method
);
}
Method
[] declaredMethods
= aClass
.getDeclaredMethods();
for (Method declaredMethod
: declaredMethods
) {
System
.out
.println(declaredMethod
);
}
Method show
= aClass
.getMethod("show");
Object invoke
= show
.invoke(o
);
Method show1
= aClass
.getMethod("show1", int.class);
Object invoke1
= show1
.invoke(o
, 23);
Method show2
= aClass
.getDeclaredMethod("show2", String
.class, int.class);
show2
.setAccessible(true);
Object lee
= show2
.invoke(o
, "zhangsan", 24);
}
}
无参构造调用了
public java
.lang
.String com
.westore
.reflect
.Student
.toString()
public void com
.westore
.reflect
.Student
.show()
public void com
.westore
.reflect
.Student
.show1(int)
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 boolean java
.lang
.Object
.equals(java
.lang
.Object
)
public native int java
.lang
.Object
.hashCode()
public final native java
.lang
.Class
java.lang.Object.getClass()
public final native void java
.lang
.Object
.notify()
public final native void java
.lang
.Object
.notifyAll()
public java
.lang
.String com
.westore
.reflect
.Student
.toString()
public void com
.westore
.reflect
.Student
.show()
public void com
.westore
.reflect
.Student
.show1(int)
private void com
.westore
.reflect
.Student
.show2(java
.lang
.String
,int)
空参方法
23
zhangsan
==24
反射与泛型
在JDK5之后加入了泛型这个功能,name使用反射就可以对泛型做一些事情。比如说使用反省可以避免强制转换:
public class demo4 {
public static <T> T
getInstance(Class
<T> cls
){
try {
return cls
.getConstructor().newInstance();
}catch (Exception e
) {
e
.printStackTrace();
return null
;
}
}
public static void main(String
[] args
) {
Date d
=demo0806
.getInstance(Date
.class);
JFrame frame
=demo0806
.getInstance(JFrame
.class);
}
}
接下来当使用这个demo的时候,无须强制转换,系统会执行严格检查,进一步的如果对Array进行操作可以再改写成:
public class Demo5 {
public static void main(String
[] args
) throws NoSuchMethodException
, InvocationTargetException
, IllegalAccessException
{
ArrayList
<Integer> arrayList
=new ArrayList<>();
arrayList
.add(100);
arrayList
.add(200);
Class
<? extends ArrayList> aClass
= arrayList
.getClass();
Method add
= aClass
.getMethod("add", Object
.class);
Object o
= add
.invoke(arrayList
, "反射");
for (int i
=0;i
<arrayList
.size();i
++){
System
.out
.println(arrayList
.get(i
));
}
}
}
100
200
反射