JAVA反射机制
2016-06-21 22:58
323 查看
一、Java反射机制的概念:
在程序运行时,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取信息以及动态调用对象的方法的功能称为java语言的反射机制。
二、功能:
在程序运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
三、API使用示例
[java] view plain copy
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
* 反射学习笔记
*/
public class ReflectDemo {
public static void main(String[] args) {
try {
//获得Class对象的三种方式
//方式一:
Class class1 = int.class; //8个基本数据类型和一个特殊类型void获取Class对象的方式
class1 = Cat.class;
//包装类的获取方式
class1 = Integer.class;
class1 = Integer.TYPE;
//方式二:
//引用类型
class1 = "abc".getClass();
class1 = new String().getClass();
class1 = new Cat().getClass();
//方式三:
class1 = Class.forName("java.lang.String");
//基本类型和包装类型的Class对象
Class<Boolean> booleanClass = boolean.class;
Class<Boolean> booleanClass2 = Boolean.TYPE;
//比较的是内存中的字节码文件,而非字节码文件中的内容
System.out.println("boolean.class==Boolean.TYPE: " + (booleanClass == booleanClass2));
Class<Byte> byteClass = byte.class;
Class<Byte> byteClass2 = Byte.TYPE;
System.out.println("byte.class==Byte.TYPE: " + (byteClass == byteClass2));
Class<Character> charClass = char.class;
Class<Character> charClass2 = Character.TYPE;
System.out.println("char.class==Character.TYPE: " + (charClass == charClass2));
Class<Short> shortClass = short.class;
Class<Short> shortClass2 = Short.TYPE;
System.out.println("short.class==Short.TYPE: " + (shortClass == shortClass2));
Class<Integer> integerClass = Integer.TYPE;
Class<Integer> intClass = int.class;
System.out.println("int.class==Integer.TYPE: " + (intClass == integerClass));
Class<Long> longClass = long.class;
Class<Long> longClass2 = Long.TYPE;
System.out.println("long.class==Long.TYPE: " + (longClass == longClass2));
Class<Float> floatClass = float.class;
Class<Float> floatClass2 = Float.TYPE;
System.out.println("float.class==Float.TYPE: " + (floatClass == floatClass2));
Class<Double> doubleClass = double.class;
Class<Double> doubleClass2 = Double.TYPE;
System.out.println("double.class==Double.TYPE: " + (doubleClass == doubleClass2));
Class<Void> voidClass = void.class;
Class<Void> voidClass2 = Void.TYPE;
System.out.println("void.class==Void.TYPE: " + (voidClass == voidClass2));
System.out.println("int[][].class == int[][].class: " + (int[][].class == int[][].class));
//判断数据类型
System.out.println("int.class.isPrimitive(): " + int.class.isPrimitive()); //判断是否基本数据类型
System.out.println("Integer.class.isPrimitive(): " + Integer.class.isPrimitive());
System.out.println("int[].class.isPrimitive(): " + int[].class.isPrimitive());
System.out.println("int[].class.isArray(): " + int[].class.isArray()); //判断是否数组类型
System.out.println("---------------------------------------");
Class<Cat> classz = Cat.class;
// 调用无参的公共构造方法
Constructor<Cat> constructor = classz.getConstructor(null);
Cat cat = constructor.newInstance(null);
// 调用带参数的公有构造方法
constructor = classz.getConstructor(String.class);
cat = constructor.newInstance("汤姆猫");
System.out.println(cat.getName());
//调用带参的私有构造方法
constructor = classz.getDeclaredConstructor(String.class,String.class);
constructor.setAccessible(true);
cat = constructor.newInstance("不吃老鼠的猫","黄猫");
//获得一个属性的值(公共的)
Field fieldName = classz.getField("name");
System.out.println(fieldName.get(cat));
fieldName.set(cat, "美猫猫");
System.out.println(fieldName.get(cat));
//私有的
fieldName = classz.getDeclaredField("type");
fieldName.setAccessible(true);
fieldName.set(cat,"挪威森林猫");
System.out.println(fieldName.get(cat));
//调用无参的公共方法
Method method = classz.getMethod("catchMouse", null);
method.invoke(cat, null);
//调用带参的公共方法
method = classz.getMethod("eat", String.class);
method.invoke(cat, "鱼");
//调用私有方法
method = classz.getDeclaredMethod("display", null);
method.setAccessible(true);
method.invoke(cat, null);
//调用带数组参数的方法
Class arraysClass = Class.forName("java.util.Arrays"); //加载内存中java.util.Arrays的Class字节码文件
Method arrayMethod = arraysClass.getMethod("sort", int[].class);
int[] nums = {3,5,9,2,6,10};
arrayMethod.invoke(null, nums); //因为sort是java.util.Arrays类的静态方法,不需要实例对象,所以第一个参数为null
arrayMethod = arraysClass.getMethod("toString", int[].class);
System.out.println(arrayMethod.invoke(null, nums)); //打印排序后的数组
//获得父类信息
System.out.println(classz.getSuperclass().getName()); //获得父类的名称
Class superClass = classz.getSuperclass();
Method[] methods = superClass.getDeclaredMethods(); //获得父类的所有方法,包括私有方法
for (Method method2 : methods) {
System.out.print(method2.getName() + " ");
}
System.out.println();
//判断是否抽象类,用java.lang.reflect.Modifier类可以获得一个类中成员的访问修饰符
int modifier = superClass.getModifiers();
System.out.println(Modifier.isAbstract(modifier));
//获得父类的所有属性,包括私有的
Field[] fields = superClass.getDeclaredFields();
for (Field field : fields) {
System.out.print(field + " ");
}
System.out.println();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 动物
*/
abstract class Animal {
/**
* 名称
*/
public String name;
/**
* 颜色
*/
private String color;
/**
* 年龄
*/
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
/**
* 吃东西
*
* @param name
*/
public abstract void eat(String name);
}
/**
* 猫
*
*/
class Cat extends Animal {
/**
* 猫的种类
*/
private String type;
public Cat() {
System.out.println("Cat");
}
private Cat(String name,String type) {
this.name = name;
this.type = type;
}
public Cat(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
/**
* 抓老鼠
*/
public void catchMouse() {
System.out.println("抓老鼠。。。");
}
@Override
public void eat(String foodName) {
System.out.println("猫吃" + foodName + "。");
}
/**
* 显示猫的名称
*/
private void display() {
System.out.println("name:" + name);
}
}
在程序运行时,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取信息以及动态调用对象的方法的功能称为java语言的反射机制。
二、功能:
在程序运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
三、API使用示例
[java] view plain copy
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
* 反射学习笔记
*/
public class ReflectDemo {
public static void main(String[] args) {
try {
//获得Class对象的三种方式
//方式一:
Class class1 = int.class; //8个基本数据类型和一个特殊类型void获取Class对象的方式
class1 = Cat.class;
//包装类的获取方式
class1 = Integer.class;
class1 = Integer.TYPE;
//方式二:
//引用类型
class1 = "abc".getClass();
class1 = new String().getClass();
class1 = new Cat().getClass();
//方式三:
class1 = Class.forName("java.lang.String");
//基本类型和包装类型的Class对象
Class<Boolean> booleanClass = boolean.class;
Class<Boolean> booleanClass2 = Boolean.TYPE;
//比较的是内存中的字节码文件,而非字节码文件中的内容
System.out.println("boolean.class==Boolean.TYPE: " + (booleanClass == booleanClass2));
Class<Byte> byteClass = byte.class;
Class<Byte> byteClass2 = Byte.TYPE;
System.out.println("byte.class==Byte.TYPE: " + (byteClass == byteClass2));
Class<Character> charClass = char.class;
Class<Character> charClass2 = Character.TYPE;
System.out.println("char.class==Character.TYPE: " + (charClass == charClass2));
Class<Short> shortClass = short.class;
Class<Short> shortClass2 = Short.TYPE;
System.out.println("short.class==Short.TYPE: " + (shortClass == shortClass2));
Class<Integer> integerClass = Integer.TYPE;
Class<Integer> intClass = int.class;
System.out.println("int.class==Integer.TYPE: " + (intClass == integerClass));
Class<Long> longClass = long.class;
Class<Long> longClass2 = Long.TYPE;
System.out.println("long.class==Long.TYPE: " + (longClass == longClass2));
Class<Float> floatClass = float.class;
Class<Float> floatClass2 = Float.TYPE;
System.out.println("float.class==Float.TYPE: " + (floatClass == floatClass2));
Class<Double> doubleClass = double.class;
Class<Double> doubleClass2 = Double.TYPE;
System.out.println("double.class==Double.TYPE: " + (doubleClass == doubleClass2));
Class<Void> voidClass = void.class;
Class<Void> voidClass2 = Void.TYPE;
System.out.println("void.class==Void.TYPE: " + (voidClass == voidClass2));
System.out.println("int[][].class == int[][].class: " + (int[][].class == int[][].class));
//判断数据类型
System.out.println("int.class.isPrimitive(): " + int.class.isPrimitive()); //判断是否基本数据类型
System.out.println("Integer.class.isPrimitive(): " + Integer.class.isPrimitive());
System.out.println("int[].class.isPrimitive(): " + int[].class.isPrimitive());
System.out.println("int[].class.isArray(): " + int[].class.isArray()); //判断是否数组类型
System.out.println("---------------------------------------");
Class<Cat> classz = Cat.class;
// 调用无参的公共构造方法
Constructor<Cat> constructor = classz.getConstructor(null);
Cat cat = constructor.newInstance(null);
// 调用带参数的公有构造方法
constructor = classz.getConstructor(String.class);
cat = constructor.newInstance("汤姆猫");
System.out.println(cat.getName());
//调用带参的私有构造方法
constructor = classz.getDeclaredConstructor(String.class,String.class);
constructor.setAccessible(true);
cat = constructor.newInstance("不吃老鼠的猫","黄猫");
//获得一个属性的值(公共的)
Field fieldName = classz.getField("name");
System.out.println(fieldName.get(cat));
fieldName.set(cat, "美猫猫");
System.out.println(fieldName.get(cat));
//私有的
fieldName = classz.getDeclaredField("type");
fieldName.setAccessible(true);
fieldName.set(cat,"挪威森林猫");
System.out.println(fieldName.get(cat));
//调用无参的公共方法
Method method = classz.getMethod("catchMouse", null);
method.invoke(cat, null);
//调用带参的公共方法
method = classz.getMethod("eat", String.class);
method.invoke(cat, "鱼");
//调用私有方法
method = classz.getDeclaredMethod("display", null);
method.setAccessible(true);
method.invoke(cat, null);
//调用带数组参数的方法
Class arraysClass = Class.forName("java.util.Arrays"); //加载内存中java.util.Arrays的Class字节码文件
Method arrayMethod = arraysClass.getMethod("sort", int[].class);
int[] nums = {3,5,9,2,6,10};
arrayMethod.invoke(null, nums); //因为sort是java.util.Arrays类的静态方法,不需要实例对象,所以第一个参数为null
arrayMethod = arraysClass.getMethod("toString", int[].class);
System.out.println(arrayMethod.invoke(null, nums)); //打印排序后的数组
//获得父类信息
System.out.println(classz.getSuperclass().getName()); //获得父类的名称
Class superClass = classz.getSuperclass();
Method[] methods = superClass.getDeclaredMethods(); //获得父类的所有方法,包括私有方法
for (Method method2 : methods) {
System.out.print(method2.getName() + " ");
}
System.out.println();
//判断是否抽象类,用java.lang.reflect.Modifier类可以获得一个类中成员的访问修饰符
int modifier = superClass.getModifiers();
System.out.println(Modifier.isAbstract(modifier));
//获得父类的所有属性,包括私有的
Field[] fields = superClass.getDeclaredFields();
for (Field field : fields) {
System.out.print(field + " ");
}
System.out.println();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 动物
*/
abstract class Animal {
/**
* 名称
*/
public String name;
/**
* 颜色
*/
private String color;
/**
* 年龄
*/
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
/**
* 吃东西
*
* @param name
*/
public abstract void eat(String name);
}
/**
* 猫
*
*/
class Cat extends Animal {
/**
* 猫的种类
*/
private String type;
public Cat() {
System.out.println("Cat");
}
private Cat(String name,String type) {
this.name = name;
this.type = type;
}
public Cat(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
/**
* 抓老鼠
*/
public void catchMouse() {
System.out.println("抓老鼠。。。");
}
@Override
public void eat(String foodName) {
System.out.println("猫吃" + foodName + "。");
}
/**
* 显示猫的名称
*/
private void display() {
System.out.println("name:" + name);
}
}
相关文章推荐
- Effictive Java 并发摘录
- Struts2系列:(4)使用多个struts配置文件
- struts2 根空间和默认命名空间区别
- Java中多线程知识点总结
- myeclipse清理缓存方法(图解)
- Spring Data 系列(一) 入门
- Eclipse创建maven项目的详细过程
- Java中的值传递和引用传递
- spring+springmvc+mybatis框架的搭建
- 《第一行代码》-1.4.添加LogCat到eclipse及初步使用LogCat
- Quartz+spring
- Spring Security入门Demo
- java线程协作,经典生产者/消费者模式(二、Lock和Condition)
- Java - PAT - 1001. A+B Format (20)
- java可变参数
- Struts2系列:(3)Action的访问路径和缺省后缀
- springmvc+mybatis批量上传文件
- Struts2常用标签总结
- MyEclipse和IntelliJ IDEA安装使用SVN
- Spring实例化的3种方式