Java笔记--09

来源:互联网 发布:获取访客手机号码源码 编辑:程序博客网 时间:2024/06/14 05:49

以下是SUN提供的反射机制中的类
java.lang.Class;
java.lang.reflect.Construct;
java.lang.reflect.Filed;
java.lang.reflect.Modifier;
反射机制的作用:
1.反编译:.class–>.java
2.通过反射机制访问java类的属性,方法,构造方法等
获取Class类型对象的三种方式
第一种方式:

Class c1 = Class.forName("User");

第二种方式:

//java中每个类型都有class属性Class c2 = User.class;

第三种方式:

//java语言中任何一个java对象都有getClass方法User u = new User();Class c3 = u.getClass();
//因为User这个类在JVM中只有一个,所以c1,c2,c3的内存地址是相同的,    指向堆中唯一的一个对象System.out.println(c1==c2);//trueSystem.out.println(c2==c3);//true

注意:第一种方式中最好写类全名:带包名;c1,c2,c3代表User类,它们都是引用,指向JVM堆中的User对象
例如:Class c = Class.forName(“java.util.Date”);
第一种方式和第二种方式的区别

//将A.class文件装载到JVM中的过程,会执行A中的静态语句块    Class.forName("A");    //不会执行A中的静态语句块    Class c=A.class;    获取Class类型的对象之后,可以创建该类的对象    Class c = Class.forName("User");    //创建此Class对象所表示的类的一个新实例    Object o = c.newInstance();//newInstance方法调用的是无参的构造方法    if(o instanceOf User){        User u = (User)o;        System.out.println(u);    }

关于java中的可变长参数
格式:
类型… 变量
如果某方法中有可变长参数,则在方法调用的时候,传递的实参可以是0-N个
如果有可以精确匹配的方法,则调用该方法,不会再去执行可变长参数的那个方法
可变长参数只能出现一次,且只能出现在所有参数的最后一位
示例如下:

public class Test(){        //m1方法中有一个int类型可变长参数        public static void m1(int... a){//m1方法在调用的时候,传递的实参可以是0-n个            System.out.println("Test");        }        public static void m1(int i){            System.out.println(i);        }        //可变长参数可以等同看做数组        public static void m2(String... args){            for(int i=0;i<args.length;i++){                System.out.print(args[i]);            }        }        public static void m2(String... args){            for(int i=0;i<args.length;i++){                System.out.print(args[i]);            }        }        public static void main(String [] args){            m1();         //Test            m1(1);        //1   结果是1,不在执行可变长参数的m1方法,而是执行可以精确匹配的m1方法            m1(1,2);      //Test            m1(1,2,3);    //Test            m2("音乐","体育","旅行");//音乐体育旅行        }    }

IO+Properties
dbinfo.properties这样的文件我们称作配置文件,
配置文件的作用就是:使程序更加灵活
注意:一般在程序中可变的东西不要写死,推荐写到配置文件中,运行同样的程序得到不同的结果
像dbinfo这样一个具有特殊内容的配置文件我们又叫做:属性文件
java规范中要求属性文件以”.properties”作为后缀
属性文件中数据要求:
key和value之间可以使用”空格”,”冒号”,”等号”,
如果”空格”,”冒号”,”等号”都有,按最前面的作为分隔符

    //1.创建属性对象    Properties p = new Properties();//和Map一样,只不过key和value只能存储字符串类型,key不能重复,如果key重复则value值覆盖    //2.创建输入流    FileInputStream fis = new FileInputStream("dbinfo.properties");    //3.将fis流中的所有数据加载到属性对象中    p.load(fis);    //4.关闭流    fis.close();    //通过key获取value    String v = p.getPropoerty("username");    //输出到控制台    System.out.println(v);

反射机制+IO+Properties联合应用,动态创建java对象

    //1.创建属性对象    Properties p = new Properties();//和Map一样,只不过key和value只能存储字符串类型,key不能重复,如果key重复则value值覆盖    //2.创建输入流    FileReader fr = new FileReader("dbinfo.properties");    //3.将fis流中的所有数据加载到属性对象中    p.load(fr);    //4.关闭流    fr.close();    //通过key获取value    String username = p.getPropoerty("username");    //通过反射机制创建对象    Class c = Class.forName(username);    //创建对象    Object o = c.newInstance();    System.out.println(o);

java.lang.Class;
类中常用的方法:

    Class forName();    Field [] getDeclaredFields();    Field  getDeclaredField(Steing name);    Method[] getDeclaredMethods();    Method getDeclaredMethod(String name,Class... parameterType);    Constructors[] getDeclaredConstructors();    Constructors getDeclaredConstructor(Class... parameterType);    String getName();    String getSimpleName();    int getModifiers();    newInstance();    String toString();    Class getSuperclass();    Class[] getInterfaces();

java.lang.reflect.Field;类中的属性
//要想获取类中的属性,首先要获取整个类
Class c = Class.forName(“User”);
//获取属性Field
Field [] fs = c.getFields();//该方法获取的是所有public修饰的属性
//获取所有属性
Field fs = c.getDeclaredFields();

for(Field field:fs){
int i = field.getModifiers();//获取属性的修饰符对应的数字
String strModifier = Modifier.toString(i);//将该数字转换成对应的字符串修饰符
Class type = field.getType();//获取属性的类型对应的类
String strType = type.getSimpleName();//将该类转换成对应的字符串类型
}
下面演示通过反编译获取类和类中的属性

    Class c = Class.forName("User");    Field fs = c.getDeclaredFields();    StringBuffer sb = new StringBuffer();    sb.append(Modifier.toString(c.getModifiers())+"  class  "+c.getSimpleName()+"{/n");    for(Field field:fs){        sb.append("\t");        sb.append(Modifier.toString(field.getModifiers())+" ");        sb.append(field.getType().getSimpleName()+" ");        sb.append(field.getName()+";/n");    }    sb.append("}");    System.out.println(sb);

怎样获取类中某个特定的属性并对其进行修改?

    //获取类    Class c = Class.forName("User");    //获取id属性    Field idF = c.getDeclaredField("id");//private修饰的属性获取不到,可以在创建对象之后,打破封装    Object o = c.newInstance();    idF.setAccessible(true);//使用反射机制可以打破封装,导致了java对象的属性不安全    //给o对象的id属性赋值    idF.set(o,"123");    System.out.println(idF.get(o));//123

java.lang.reflect.Method;类中的方法

    //获取类    Class c = Class.forName("User");    //获取所有的方法    Method [] ms = c.getDeclaredMethods();    for(Method m:ms){        //修饰符        System.out.println(Modifier.toString(m.getModifiers));        //方法的返回值类型        Class returnType = m.getReturnType();        String strReturnType = returnType.getSimpleName();        //方法名        String strMethodName = m.getName();        //方法的形式参数        Class [] parameterTypes = m.getParamterTypes();        for(Class parameterType:parameterTypes){            String strParameterType = parameterType.getSimpleName();        }    }

通过反射机制,获取并执行某个特定的方法

Class c = Class.forName("UserService");    //获取某个特定的方法:方法名+形参列表    Method m = c.getDeclaredMethod("login",String.class,String.class);    //通过反射机制执行login方法    Object o = c.newInstance();    //调用o对象的m方法,传递"admin","123"参数,方法的执行结果是retValue    Object retValue = m.invoke("admin","123");

java.lang.reflect.Construct;类中的构造方法

    //获取类    Class c = Class.forName("User");    //获取所有的构造方法    Construct [] cs = c.getDeclaredConstructors();    for(Construct c:cs){        //修饰符        System.out.println(Modifier.toString(c.getModifiers));        //构造方法的返回值类型        Class returnType = c.getReturnType();        String strReturnType = returnType.getSimpleName();        //构造方法名        String strMethodName = c.getName();        //构造方法的形式参数        Class [] parameterTypes = c.getParamterTypes();        for(Class parameterType:parameterTypes){            String strParameterType = parameterType.getSimpleName();        }    }

获取某个特定的构造方法并创建对象

    //获取类    Class c =Class.forName("User");    //获取特定的构造方法    Constructor con = c.getDeclaredConstructor(String.class,int.class);    //创建对象    Object o = con.newInstance("张三",21);

关于类获取父类和父接口

//通过反射机制获取String类的父类和父接口    //获取类    Class c = Class.forName("java.lang.String");    //获取父类    Class superClass = c.getSuperclass();    System.out.println(superClass.getName());    //获取父接口    Class[] ins = c.getInterfaces();    for(Class in:ins){        System.out.println(in.getName());    }
原创粉丝点击