二十、反射机制、可变长参数
1、SUN提供的反射机制中的类:
1)反射机制的含义:
java反射机制是在运行状态中,对于任何一个类,都能够知道这个类的属性和方法;对于任何一个对象,都能调用它的任何一个方法和属性;这种动态获取信息以及动态调用对象的方法的功能称为java语言的反射机制
2)动态语言的含义:
程序运行时,运行改变程序结构或变量类型,这种语言称为动态语言。从该观点上看,perl、python、ruby是动态语言。C++、java、C#不是动态语言。但是java语言有一个非常突出的动态机制:Reflection。这个动态机制在java上指的是:我们可以于运行时加载、探知、使用编译期间完全未知的Classes,换句话说java程序可以加载一个运行时才得知名称的Class,获悉其完整结构(但不包含methods定义),并生成其对象实体,或对其fields设置,或唤起methods。
3)java反射机制主要提供的功能
在运行时判断任意一个对象所属的类;
在运行时构造任意一个类的对象;
在运行时判断任意一个类所具有的成员方法和成员变量;
在运行时调用任意一个对象的方法,生成动态代理;
java.lang.Class; //Class类 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的
java.lang.reflect.Constructor;
java.lang.reflect.Filed;
java.lang.reflect.Method;
java.lang.reflect.Modifier;
//获取Class类型对象的三种方式:
public class ReflectTest01 {
public static void main(String[] args) throws ClassNotFoundException {
//方法一:c1引用保存内存地址指向堆中的对象,给对象代表的是Employee.class整个类
Class c1 = Class.forName("反射机制.Employee");//此处要是不加包名的话可能会报类没有找到的异常
//方法二:java中每一个类型都有class属性,其形象的表示了c2代表整个Employee.class文件
Class c2=Employee.class;
//方法三:java语言中任何一个java对象都有getClass方法
Employee e1=new Employee();
Class c3=e1.getClass();
System.out.println(c1==c2);
System.out.println(c2==c3);
}
}
public class Employee {
String name;
public Employee(){
}
public Employee(String name){
this.name=name;
}
public void m1(String name){
System.out.println(name+"在工作");
}
}
|Class类中静态语句块的执行|
public class ReflectTest02 {
public static void main(String[] args) throws ClassNotFoundException {
//不会执行静态语句块
Class class1=A.class;
//将A.class文件装载到jvm中的过程,静态语句块会执行
Class class2=Class.forName("反射机制.A");
//静态语句块会执行
A a=new A();
Class class3=a.getClass();
try {
A a2=(A) class3.newInstance(); //创建此 Class 对象所表示的类的一个新实例
System.out.println(a==a2);//false
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class A{
static {
System.out.println("A-->中的静态语句块执行");
}
}
2、可变长参数
public class KeBianChengCanShu {
public static void main(String[] args) {
m1();
m1(3);
String[] s={"体育","音乐","旅游","美食"};
m2(s);
}
//m1方法具有一个int 类型的可变长参数:
public static void m1(int... a){//m1方法在调用的时候传递的实参可以是0-N个
System.out.println("具有可变长参数的m1方法执行");
}
//如果有更精确匹配参数的该方法,则调用该方法,不会再去执行可变长参数的那个方法
public static void m1(int i){
System.out.println("具有精确匹配参数的m1方法执行");
}
//可变长参数可等同看做一个数组:
public static void m2(String[] args){
for(int i=0;i<args.length;i++){
System.out.println(args[i]);
}
}
//可变长参数只能出现一次,并且只能出现在所有参数的最后一位
//public static void m3(String... a,int i){} //这种写法是不对的
public static void m3(int i,String... s){
}
}
|Properties属性集类的用法|:读取属性配置文件中的key 和 value值
dbProperties文件中的内容:
username:zhangsan
password:zs123
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
public class ReflectTest03 {
public static void main(String[] args) {
//创建属性对象:
Properties p=new Properties();
FileInputStream fiStream=null;
try {
//创建输入流
fiStream=new FileInputStream("src/反射机制和可变长参数/dbProperties");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
// 从输入流中读取属性列表(键和元素对)
p.load(fiStream);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
fiStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//通过key获取value:
String s1=p.getProperty("username");
String s2=p.getProperty("password");
System.out.println(s1);
System.out.println(s2);
}
}
|示例:反射机制给属性赋值|
import java.lang.reflect.Field;
public class ReflectTest06 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException {
//以前给类属性赋值
User user=new User();
user.name="zhangsan";
System.out.println(user.getName());
//获取类
Class c=Class.forName("反射机制和可变长参数.User");
//获取name属性-->可以通过打破封装性,对其赋值
Field nameField=c.getDeclaredField("name");
//打破封装
nameField.setAccessible(true);
Object ob=c.newInstance();
//给ob 对象的name属性赋值 nana
nameField.set(ob, "nana");
System.out.println(nameField.get(ob));
}
}
|示例:用反射机制反编译某个类中的属性信息|
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class ReflectTest05 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException {
Class c=Class.forName("反射机制和可变长参数.User");
//获取类名:
System.out.println(c.getSimpleName());
//获取所有的Public修饰的属性
Field[] fields=c.getFields();
System.out.println(fields.length);
for(int i=0;i<fields.length;i++){
//属性对象代表的属性的简单的名字
System.out.println(fields[i].getName());
//属性的详细的信息,包括该属性的修饰符
System.out.println(fields[i]);
}
Field fields2=c.getDeclaredField("name");
System.out.println(fields2);
StringBuffer sb=new StringBuffer();
sb.append(Modifier.toString(c.getModifiers())+"class"+c.getSimpleName()+"{\n");
for(Field fs:fields){
sb.append("\t");
sb.append(Modifier.toString(fs.getModifiers())+" ");
sb.append(fs.getType().getSimpleName()+" ");
sb.append(fs.getName()+";\n");
}
sb.append("}");
System.out.println(sb);
}
}
|示例:通过反射机制执行某个特定的方法|
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/*
通过反射机制执行某个方法
*/
public class ReflectTest08 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Class c=Class.forName("反射机制和可变长参数.CustomerService");
//获取某个特定的方法:通过方法名+形参列表
Method m=c.getDeclaredMethod("login",String.class,String.class);
//通过反射机制执行login方法
Object ob=c.newInstance();
//调用o对象的m方法,传递"admin","123"参数,方法执行的结果是reValue
Object reValue=m.invoke(ob, "admin","123");
System.out.println(reValue);
}
}
public class CustomerService {
//登录
public boolean login(String username,String password){
if("admin".equals(username)&&"123".equals(password)){
return true;
}
return false;
}
//退出
public void logout(){
System.out.println("已经退出系统");
}
}

浙公网安备 33010602011771号