1.动态语言 静态语言
动态语言:
- 运行时可以改变自身结构的语言
- eg: JavaScript, C#, PHP, Python
静态语言:
- 运行时结构不可变的语言
- eg: Java, C, C++
Java 不是动态语言,但通过反射机制获得了类似动态语言的特性,具有了一定的动态性,使得代码更加灵活。
2. Reflection 反射
反射机制使得程序可以在运行期间使用反射机制的API类获取任何类的内部信息,并直接操作类所有的属性和方法(包括private修饰的属性和方法)。
类加载结束后,在堆内存的方法区中产生了一个Class类型的对象,这个对象包含了类的所有信息。我们可以通过这个对象来了解类,所以称为反射。(与通过类来创建对象的过程相反)
一个类只有一个Class类型的对象。
代码示例:
package AnnotationTest;
public class A3 {
public static void main(String[] args) throws ClassNotFoundException {
//获取类的Class对象
Class<?> c1 = Class.forName("AnnotationTest.A31");
System.out.println(c1.toString());
System.out.println(c1.getName());
System.out.println(c1.hashCode());
Class<?> c2 = Class.forName("AnnotationTest.A31");
Class<?> c3 = Class.forName("AnnotationTest.A31");
System.out.println(c2.hashCode());
System.out.println(c3.hashCode());
//hashcode相同说明是同一个对象,说明一个类只有一个Class类型的对象
}
}
//用一个实体类作示例,来取得它的Class类型的对象
class A31{
int di;
int num;
String name;
boolean falg;
A31(){
}
public A31(int di, int num, String name, boolean falg) {
this.di = di;
this.num = num;
this.name = name;
this.falg = falg;
}
public int getDi() {
return di;
}
public void setDi(int di) {
this.di = di;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isFalg() {
return falg;
}
public void setFalg(boolean falg) {
this.falg = falg;
}
@Override
public String toString() {
return "A31{" +
"di=" + di +
", num=" + num +
", name='" + name + '\'' +
", falg=" + falg +
'}';
}
}
3.Class类
特征:
方法:
4.获取Class类型的对象的五种方法
方法一:通过包名+类名获取Class对象,会抛出ClassNotFoundException异常。
Class<?> c1 = Class.forName("AnnotationTest.A31");
System.out.println(c1.hashCode());
方法二:通过类的对象获取Class对象
A31 a = new A31();
Class c2 = a.getClass();
System.out.println(c2.hashCode());
方法三:通过类的class属性获取Class对象。该方法最安全,性能最高。
Class<A31> c3 = A31.class;
System.out.println(c3.hashCode());
方法四:通过子类的Class对象获取父类的Class对象
Class c4 = c2.getSuperclass();
System.out.println(c4 + " " + c4.hashCode());
方法五:通过基本内置类型的包装类型的type属性获取Class对象
Class<Integer> c5 = Integer.TYPE;
System.out.println(c5 + " " + c5.hashCode());
完整代码示例:
package AnnotationTest;
public class A3 {
public static void main(String[] args) throws ClassNotFoundException {
//方法一:通过包名+类名获取Class对象
Class<?> c1 = Class.forName("AnnotationTest.A31");
System.out.println(c1.hashCode());
//方法二:通过类的对象获取Class对象
A31 a = new A31();
Class c2 = a.getClass();
System.out.println(c2.hashCode());
//方法三:通过类的class属性获取Class对象
Class<A31> c3 = A31.class;
System.out.println(c3.hashCode());
//方法四:通过子类的Class对象获取父类的Class对象
Class c4 = c2.getSuperclass();
System.out.println(c4 + " " + c4.hashCode());
//方法五:通过基本内置类型的包装类型的type属性获取Class对象
Class<Integer> c5 = Integer.TYPE;
System.out.println(c5 + " " + c5.hashCode());
}
}
class A31 extends Object{
int di;
int num;
String name;
boolean falg;
A31(){
}
public A31(int di, int num, String name, boolean falg) {
this.di = di;
this.num = num;
this.name = name;
this.falg = falg;
}
public int getDi() {
return di;
}
public void setDi(int di) {
this.di = di;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isFalg() {
return falg;
}
public void setFalg(boolean falg) {
this.falg = falg;
}
@Override
public String toString() {
return "A31{" +
"di=" + di +
", num=" + num +
", name='" + name + '\'' +
", falg=" + falg +
'}';
}
}