反射
反射(RTTI)
动态加载一个指定的类,并获取该类中的所有的内容。而且将字节码文件封装成对象,并将字节码文件中的内容都封装成对象,这样便于操作这些成员。简单说:反射技术可以对一个类进行解剖。
反射的好处:大大的增强了程序的扩展性。
反射的基本步骤:
1、获得Class对象,就是获取到指定的名称的字节码文件对象。
2、实例化对象,获得类的属性、方法或构造函数。
3、访问属性、调用方法、调用构造函数创建对象。
( run-time type identification )包:java.lang.reflection
Class是一个类,用来描述类型的信息,每一种类型都有且只有一个Class对象与其一一对应。Class对象是反射的源头。
//获得Class对象的方式:
//1、通过对象(引用)调用从Object类中继承来的getClass方法
//2、通过类名调用.class属性
//3、通过Class类中的静态方法forName()常用
//Class对象的作用:1、分析类的结构 2、实现反射
//reflect包下的三个类:Constructor Field Method
获取这个Class对象,有三种方式:
使用的Class类中的方法,静态的forName方法。
扩展性最强
// 1. 根据给定的类名来获得 用于类加载
String classname = "cn.itcast.reflect.Person";// 来自配置文件
Class clazz = Class.forName(classname);// 此对象代表Person.class
// 2. 如果拿到了对象,不知道是什么类型 用于获得对象的类型
Object obj = new Person();
Class clazz1 = obj.getClass();// 获得对象具体的类型
// 3. 如果是明确地获得某个类的Class对象 主要用于传参
Class clazz2 = Person.class;
Class类本身不提供构造方法,因此不能使用new运算符和构造方法显式地创建一个Class对象。
Class类是用来描述类型的信息的
Class:对类的描述或是类的描述文件
Class类的对象与类一一对应
Class对象的作用:1、分析类的结构 2、实现反射
Class是反射的源头
获得Class对象的三种方式:1、Object类中继承的getClass方法 2、类名.class
Student obj = new Student();
Class c1 = obj.getClass();
Class c2 = Student.class;*/
Class c3 = Class.forName("com.aowin.rtti.Student");//包名+类名
System.out.println(c3.getName());//打印结果com.aowin.rtti.Student
System.out.println(c3.getSimpleName());打印结果Student
//创建对象
/*Object obj = c3.newInstance();//必须Student类中要有无参数的构造方法
创建对象后调用方法
Student stu = (Student)obj;
stu.eat();*/
//获得构造方法
//获得无参数的私有权限的构造方法
Constructor con=c3.getDeclaredConstructor();
con.setAccessible(true);
Object obj=con.newInstance();
获得有参数的构造方法
Constructor con = c3.getConstructor(int.class);//获得指定公共权限的构造方法
Constructor con = c3.getDeclaredConstructor(int.class);//获得指定的所有权限的构造方法
con.setAccessible(true);//如果获得的是私有权限的构造方法 ,要设置为可以改动
Object obj = con.newInstance(1000);
//获得属性
Field field = c3.getField("age");//获得指定的公共权限的属性 包括父类中继承的属性
Field field = c3.getDeclaredField("age");//获得指定的任意权限的属性
Object obj = c3.newInstance();
field.setAccessible(true);
field.set(obj, 20);//第一个参数是指定的对象 第二个参数是值
Object temp = field.get(obj);//获取指定对象的属性的值,返回对象 obj 中的所表示字段的值
System.out.println(temp);*/
//获得方法 反射的执行方法
//Method method = c3.getMethod("eat",int.class);
/*Method method = c3.getDeclaredMethod("eat",int.class);
Object obj = c3.newInstance();
method.setAccessible(true);
method.invoke(obj,100);*///执行method对象所代表的方法
获得无参数的方法
Method me=c3.getMethod("eat");
Object obj=c3.newInstance();
me.setAccessible(true);
me.invoke(obj);
Constructor[] cons = c3.getConstructors();//获得公共权限的所有用构造方法
Constructor[] cons = c3.getDeclaredConstructors();//获得任意权限的所有构造方法
for(Constructor temp:cons){//for each循环
System.out.println(temp);
}
Field[] fs = c3.getFields();//包括父类中继承的属性
Field[] fs = c3.getDeclaredFields();//不包括继承来的
for(Field f:fs){
System.out.println(f);
}
Method[] ms = c3.getMethods();//公共权限的所有方法,包括继承来的
Method[] ms = c3.getDeclaredMethods();//获得任意权限的所有方法,不包括继承来的
for(Method m:ms){
System.out.println(m);
}
str.replace(“”,“”);去掉所有空格,包括首尾、中间
trim()是去掉首尾空格
1、判断类型是否相同
传统转型:.instanceof if(x instanceof Dog) //这种运算符是使用老式关键字,他要求x必须为引用,所以不能用基本类型变量名,而后面的Dog也必须是Class,所以还是不能用基本类型.同时有个缺点就是Dog本身必须是Class名,根本不能用某种变量替换,相比于下面的方法缺少灵活性.
2.操作Class对象:
Class.isInstance(obj)//比如
Class c=Dog.class;
if(c.isInstance(x))....obj也要求是object
a、关键字 instanceof ;//判断对象是否实现了指定的接口或继承了指定的类
b.关键字 isInstance
格式:<对象 instanceof 类型> ,判断一个对象是否所属于指定的类型。
student instanceof Person = true;//student继承了person类
Object obj = new Student();
obj = new String();
if(obj instanceof Student){
System.out.println("是student类型");
}
if(c3.isInstance(obj)){
System.out.println("是student类型");
}
System.out.println(c3.getName());
System.out.println(c3.getSimpleName());
当
Object obj = new Student();时//是同一类型
打印结果为是student类型
是student类型
com.aowin.rtti.Student
Student
当obj = new String();时 // 不同一类型
结果为com.aowin.rtti.Student
Student
java中有三种移位运算符
<< : 左移运算符,num << 1,相当于num乘以2
>> : 右移运算符,num >> 1,相当于num除以2
>>> : 无符号右移,忽略符号位,空位都以0补齐
无符号右移,忽略符号位,空位都以0补齐
value >>> num -- num 指定要移位值value 移动的位数。
无符号右移的规则只记住一点:忽略了符号位扩展,0补最高位 无符号右移运算符>>> 只是对32位和64位的值有意义