LOFTER for ipad —— 让兴趣,更有趣

点击下载 关闭
java EE开发之Servlet第十课:反射基础二
hnxmx2019 2023-04-20


##一.反射类中的属性

在Java中一切皆对象,那么类中任何一个属性都可以看做一个对象,一 个属性对应一个Field对象


####1.先建一个普通的类,写上不同修饰类型的属性


public class Student {

public String name;

protected int age;

String sex;

private double money;

public static String phone;

public static final String email = "xiaoma@qq.com";

public Date brithday;

public Student() {

this.name = "tom";

System.out.println("无参构造方法调用...");

}

public Student(String name, int age) {

this.name = name;

this.age = age;

}

public Student(String name) {

this.name = name;

System.out.println("一参构造方法调用...");

}

private Student(double money) {

this.money = money;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public String getSex() {

return sex;

}


public void setSex(String sex) {

this.sex = sex;

}

public double getMoney() {

return money;

}

public void setMoney(double money) {

this.money = money;

}

public static String getPhone() {

return phone;

}

public static void setPhone(String phone) {

Student.phone = phone;

}

public Date getBrithday() {

return brithday;

}

public void setBrithday(Date brithday) {

this.brithday = brithday;

}

public static String getEmail() {

return email;

}

private void sleep() {

System.out.println("睡啊睡...");

}

public void a(int a, int b) {


}

}


####2,反射加载类并实例化


Class c = Class.forName("com.accp.entity.Student");

Student stu = (Student)c.newInstance();

####3,获取指定名称的公有属性


Field f1 = c.getField("name");

System.out.println(f1);


stu.name = "james";

/*通过反射的方式,给属性赋值*/

f1.set(stu, "james");

/*  通过属性对象,调用get()方法,参数是stu对象

通过属性对象,调用get()方法,参数是stu对象*/

System.out.println(f1.get(stu));


####4,获取公有(静态)属性



Field ff = c.getField("phone");


stu.name = "138888";

ff.set(stu, "138888");

/*反射获取属性值*/

System.out.println(ff.get(stu));



5,获取指定名称的非公有属性


Field f2 = c.getDeclaredField("money");

/*解锁*/

f2.setAccessible(true);

f2.set(stu, 8888.8);//赋值

System.out.println(f2.get(stu));//取值



####6,获取指定类的所有公有属性


Field [] fields = c.getFields();

for(Field ff:fields){

    System.out.println(ff);

}



####7,获取指定类的所有公有属性



Field [] fields = c.getFields();

System.out.println("访问修饰符\t属性类型\t属性的名字");

for(Field ff:fields){

/*操作属性对象,获取其中每一部分*/

/*获取访问修饰符*/

System.out.println(soEasy(ff.getModifiers())+"\t"+

ff.getType().getSimpleName()+"\t"+

ff.getName());

}

/*自定义将返回的访问修饰符int类型转换为String类型*/

public static String soEasy(int modifier){

return Modifier.toString(modifier);

}


####8,获取所有的属性


Field [] fields = c.getDeclaredFields();

for(Field ff:fields){

//System.out.println(ff);

System.out.println(soEasy(ff.getModifiers())+"\t"+

ff.getType().getSimpleName()+"\t"+

ff.getName());

}



##二.反射类中的方法


在Java中一切皆对象,那么类中任何一个方法都可以看做一个对象,一个方法对应一个Method对象

加载类并初始化


Class c = Class.forName("com.accp.entity.Student");

/*反射创建Student 对象*/

Student stu = (Student)c.newInstance();



1,获了指定名称的公有方法



Method m1 =  c.getMethod("setName", String.class);

m1.invoke(stu, "小牛");//调用setName()方法,其实就是赋值


Method m2 = c.getMethod("getName");

System.out.println(m2.invoke(stu));//调用m2:getName()方法



2,获取指定名称的非公有方法



Method m3 =  c.getDeclaredMethod("sleep");

m3.setAccessible(true);//解锁

m3.invoke(stu);



3,获取全部的公有方法(包括父亲的);



Method [] ms1 = c.getMethods();

for(Method mm:ms1){

//System.out.println(mm);   

System.out.println(soEasy(mm.getModifiers())+"\t"+

  mm.getReturnType().getSimpleName()+"\t"+

  parse(mm.getParameterTypes()));

}




4,获取自己声明方法(公有、私有),就没有获取父亲的方法



Method [] ms1 = c.getMethods();

for(Method mm:ms1){

//System.out.println(mm);   

System.out.println(soEasy(mm.getModifiers())+"\t"+

  mm.getReturnType().getSimpleName()+"\t"+

  parse(mm.getParameterTypes()));

}

/*自定义实现将Class类型的参数数组转换成String类型*/

public static String parse(Class [] cs){

StringBuffer sb = new StringBuffer();

sb.append("(");

for(int i=0;i<cs.length;i++){

//获取class对象对应的名字,如:String.class-->String

sb.append(cs[i].getSimpleName());

//多个参数中间加一个逗号

//条件是最后一个参数后面不加逗号

if(i<cs.length-1){

sb.append(",");

}

}

sb.append(")");

return sb.toString();

}



##三,反射类中的构造方法


所有的java文件都会编译成一个class文件,与Clas类型的对象相对应在这个Class类型的对象中,包含了这个java类的属性、方法、构造方法等所有的东西。通过Class类型的对象,获取其构造方法(Constructor):可以通过构造来new出对象.



1,获取反射类无参数构造方法



/*通过Student模板对象,创建出一个实例。

  就是去动态的调用其无参构造方法*/


Class c =  Class.forName("com.accp.entity.Student");

Student stu1 = (Student)c.newInstance();

System.out.println(stu1.getName());


Constructor ct1 =  c.getConstructor();

Student stu1 =  (Student)ct1.newInstance();

System.out.println(stu1.getName());


2,获取反射类一参数的构造方法



Constructor ct2 = c.getConstructor(String.class);

Student stu2 = (Student)ct2.newInstance("jack");

System.out.println(stu2.getName());




3,获取反射类两参数的构造方法


Constructor ct3 = c.getConstructor(String.class,int.class);

Student stu3 = (Student)ct3.newInstance("marry",23);

System.out.println(stu3.getName());

System.out.println(stu3.getAge());


注意:以上的获取构造方法的前提是公有的


4,获取非公有的构造方法时,需要获取是自己声明的。



Constructor ct4 = c.getDeclaredConstructor(double.class);

//授权(解锁)

ct4.setAccessible(true);//默认是为false

Student stu4 = (Student)ct4.newInstance(2345.6);

System.out.println(stu4.getMoney());




5,获取所有的公有的构造方法的对象



Constructor [] cts1 = c.getConstructors();

for(Constructor cc:cts1){

System.out.println(cc);

}

System.out.println("==========================");


6,获取所有的构造方法的对象(包括私有的)



Constructor [] cts2 = c.getDeclaredConstructors();

for(Constructor cc:cts2){

System.out.println(cc);

}



补充: java中的可变参数


定义包含可变参数的方法


public static void test(int ... a){

int sum = 0;

for(int i=0;i<a.length;i++){

sum += a[i];

}

System.out.println(sum);

}



测试



public static void main(String[] args){

test();

test(1);

test(1,2);

test(1,2,3);

}


推荐文章
评论(0)
联系我们|招贤纳士|移动客户端|风格模板|官方博客|侵权投诉 Reporting Infringements|未成年人有害信息举报 0571-89852053|涉企举报专区
网易公司版权所有 ©1997-2025  浙公网安备 33010802010186号 浙ICP备16011220号-11 增值电信业务经营许可证:浙B2-20160599
网络文化经营许可证: 浙网文[2022]1208-054号 自营经营者信息 工业和信息化部备案管理系统网站 12318全国文化市场举报网站
网信算备330108093980202220015号 网信算备330108093980204230011号
分享到
转载我的主页