枚举、反射和内省总结
来源:互联网 发布:淘客助手mac版 编辑:程序博客网 时间:2024/05/29 12:41
主要内容:
1. 枚举知识总结
2. 枚举应用
3. 反射知识总结
4. 反射应用
5. 泛型知识总结
6. 内省总结
枚举知识总结:
2)枚举元素必须位于枚举体中的最开始部分,枚举元素列表的后要有分号与其他成员分隔。把枚举中的成员方法或变量等放在枚举元素的前面,编译器报告错误。
3)枚举只有一个成员时,就可以作为一种单例的实现方式。
枚举应用:
实现普通的next方法
实现抽象的next方法:每个元素分别是由枚举类的子类来生成的实例对象,这些子类采用类似内部类的方式进行定义。
增加上表示时间的构造方法
代码示例:
public class EnumTest {/** * * @param args */public static void main(String[] args) {// TODO Auto-generated method stub//枚举元素不用new,直接引用其元素WeekDay week1 = WeekDay.FRI;WeekDay week2 = WeekDay.FRI;System.out.println(WeekDay.THU);System.out.println(week1.equals(week2));System.out.println(week1.toString());//获取枚举常量序数System.out.println(week1.ordinal());System.out.println(TrafficLamp.RED.nextLamp());}//枚举应用一:public enum WeekDay{//调用有参数构造方法直接在元素后传参SUN,MON,TUE,WED,THU(1),FRI(2),SAT;private WeekDay(){System.out.println("first");}private WeekDay(int i){System.out.println("second");}}//枚举应用二public enum TrafficLamp{//子类采用类似内部类的方式进行定义RED(30){public TrafficLamp nextLamp(){return GREEN;}},GREEN(45){public TrafficLamp nextLamp(){return YELLOW;}},YELLOW(5){public TrafficLamp nextLamp(){return RED;}};//抽象方法public abstract TrafficLamp nextLamp();private int time;private TrafficLamp(int time){this.time = time;}public int getTime() {return time;}public void setTime(int time) {this.time = time;}}}
反射知识总结:
Class
没有公共构造方法。Class
对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的defineClass
方法自动构造的。对象.getClass(),例如,new Date().getClass()
Class.forName("类名"),例如,Class.forName("java.util.Date");
例子:String obj = (String)Class.forName("java.lang.String").newInstance();
import java.lang.reflect.Array;import java.lang.reflect.Constructor;import java.lang.reflect.Field;public class ReflectTest {/** * * @param args */public static void main(String[] args)throws Exception{String str = "abc";Class cls0 = str.getClass();Class cls1 = String.class;Class cls2 = Class.forName("java.lang.String");//打印Class类对象的toString形式System.out.println(cls0);System.out.println(cls0==cls1);System.out.println(cls2==cls1);//获得cls0所表示类的名称String strName = cls0.getName();System.out.println(strName);//用cls0创建一个新的String对象,String str1 = (String)cls0.newInstance();System.out.println(str1.isEmpty());}
Constructor类:
Constructor 提供关于类的单个构造方法的信息以及对它的访问权限。
Constructor 允许在将实参与带有底层构造方法的形参的 newInstance() 匹配时进行扩展转换,但是如果发生收缩转换,则抛出 IllegalArgumentException。
1. 得到某个类所有的构造方法:
例子:Constructor [] constructors= Class.forName("java.lang.String").getConstructors();
2. 得到某一个构造方法:
例子: Constructor constructor = Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);
3. 创建实例对象:
通常方式:String str = new String(new StringBuffer("abc"));
反射方式: String str = (String)constructor.newInstance(new StringBuffer("abc"));
4. Class.newInstance()方法:
例子:String obj = (String)Class.forName("java.lang.String").newInstance();
代码示例:
import java.lang.reflect.Array;import java.lang.reflect.Constructor;import java.lang.reflect.Field;public class ReflectTest {/** * * @param args */public static void main(String[] args)throws Exception{String str = "abc";Class cls0 = Class.forName("java.lang.String");System.out.println(cls0);//用cls0创建一个新有String对象,用有参数构造函数Constructor ctor0 = cls0.getDeclaredConstructor(String.class);//值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。//值为 false 则指示反射的对象应该实施 Java 语言访问检查。//ctor0.setAccessible(true);String str2 = (String)ctor0.newInstance("成了?");System.out.println(str2);}
Field类:
Field 提供有关类或接口的单个字段的信息,以及对它的动态访问权限,代表某个类中的一个成员变量。反射的字段可能是一个类(静态)字段或实例字段。
Array 允许在执行 get 或 set 访问操作期间进行扩展转换,但如果将发生收缩转换,则抛出一个 IllegalArgumentException。
常用方法:
1. 获得此 Class 对象所表示的类或接口的指定公共成员字段
Field getField(String s);
2. 获得此 Class 对象所表示的类或接口的指定已声明字段
Field getDeclaredField(String s);
3. 暴力访问,取消访问检查,可以访问私有字段
setAccessible(ture);
4. 获得 Field 对象所表示字段的声明类型的Class对象
Class<?> getType();
5. 获得指定对象上此 Field 表示的字段的值
Object get(Object obj) ;
代码示例:
public class ReflectTest {/** * * @param args */public static void main(String[] args)throws Exception{ReflectPoint obj = new ReflectPoint(2,5);System.out.println(obj);Field[] fields = obj.getClass().getFields();for(Field field : fields){//用String字节码来识别String字段,用"=="比,很巧妙if(field.getType() == String.class){String oldValue = (String)field.get(obj);String newValue = oldValue.replace('b', 'a');field.set(obj, newValue);}}System.out.println(obj);}
Method类:
Method 提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。所反映的方法可能是类方法或实例方法(包括抽象方法)。
Method 允许在匹配要调用的实参与底层方法的形参时进行扩展转换;但如果要进行收缩转换,则会抛出 IllegalArgumentException。
1. 得到类中的某一个方法:
例子: Method charAt = Class.forName("java.lang.String").getMethod("charAt", int.class);
2. 调用方法:
通常方式:System.out.println(str.charAt(1));
反射方式: System.out.println(charAt.invoke(str, 1));
3. 如果传递给Method对象的invoke()方法的第一个参数为null,这有着什么样的意义呢?
说明该Method对象对应的是一个静态方法!
4. jdk1.4和jdk1.5的invoke方法的区别:
Jdk1.5:public Object invoke(Object obj,Object... args)
Jdk1.4:public Object invoke(Object obj,Object[] args),
即按jdk1.4的语法,需要将一个数组作为参数传递给invoke方法时,数组中的每个元素分别对应被调用方法中的一个参数,
所以,调用charAt方法的代码也可以用Jdk1.4改写为 charAt.invoke(“str”, new Object[]{1})形式。
5. 在eclipse运行当前类的main方法,要向main方法中传递参数,该怎么做?
右键点击编辑区,选Run As菜单下Run Configurations,在参数栏里(Arguments)填上要传递的参数,保存即可。
代码示例一:调用其他类中main方法
public class ReflectTest {/** * * @param args */public static void main(String[] args)throws Exception{/** * 需求:写一个程序能调用别人的main()方法 *///常规静态调用main方法MethodDemo.main(new String[]{"aaa","bbb","1324"});//使用反射调用main方法String startingClassName = args[0];Method mainMethod = Class.forName(startingClassName).getMethod("main", String[].class);//第一个参数为空,表示该Method对象对应的是一个静态方法mainMethod.invoke(null, (Object)new String[]{"aaa","bbb","1324"});}}代码示例二:数组反射
import java.lang.reflect.Array;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.util.Arrays;public class ReflectTest {/** * * @param args */public static void main(String[] args)throws Exception{//数组的反射测试int[] ar = {1,24,4};int[][] ar2 = new int[2][3];String[] str = {"heihei","hehe","haha"};char[] ch = {'a','b','c'};//所有数组的父类都是java.lang.ObjectSystem.out.println(ar.getClass().getName());System.out.println(ar.getClass().getSuperclass().getName());System.out.println(str.getClass().getSuperclass().getName()); System.out.println(str.getClass().getName()); System.out.println(ch.getClass().getSuperclass().getName());/*//因此他们都可以和Object互转,以对象为单位,基本类型不能和对象互转,//数组本身就是一个对象Object obj1 = ar;//Object[] obj2 = ar[]; //不能这样,基本类型不能和对象互转。Object obj5= ch;Object[] obj3 = ar2; Object obj4 = str;*/System.out.println(Arrays.asList(ar));System.out.println(Arrays.asList(ch));printObject(ar);printObject(str);printObject(ch);}//利用反射方法来打印数组public static void printObject(Object obj){Class cla = obj.getClass();if(cla.isArray()){int len = Array.getLength(obj);for(int i=0; i<len; i++){System.out.println(Array.get(obj, i));}}}}
内省:Introspector
setId()的属性名——>id
isLast()的属性名——>last
setCPU的属性名是什么?——>CPU
getUPS的属性名是什么?——>UPS
总之,一个类被当作javaBean使用时,JavaBean的属性是根据方法名推断出来的,它根本看不到java类内部的成员变量。
JavaBean的优势:
2. JDK中提供了对JavaBean进行操作的一些API,这套API就称为内省。如果要你自己去通过getX方法来访问私有的x,怎么做,有一定难度吧?用内省这套api操作JavaBean比用普通类的方式更方便。
内省的综合案例:
package cn.itcast.day1;import java.beans.IntrospectionException;import java.beans.PropertyDescriptor;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class IntrospectorTestDemo {/** * @param args */public static void main(String[] args)throws Exception{// TODO Auto-generated method stubReflectPoint refp=new ReflectPoint(2,3);String propertyName="x";//"x"-->"X"-->"getX"-->MethodGetX-->//用内省的方式//获取并getX方法Object getX = getProperty(refp,propertyName);System.out.println(getX);Object value=5;//获取并调用setX方法setProperty(refp,propertyName,value);Object getX1 = getProperty(refp,propertyName);System.out.println(getX1);}//获取并调用setX方法private static void setProperty(ReflectPoint refp, String propertyName,Object value) throws IntrospectionException,IllegalAccessException, InvocationTargetException {PropertyDescriptor pd=new PropertyDescriptor(propertyName,refp.getClass());//创建对象关联Method methodSetX=pd.getWriteMethod();//获取JavaBean类中的setX方法methodSetX.invoke(refp,value);//调用setX方法}//获取并getX方法private static Object getProperty(ReflectPoint refp, String propertyName)throws IntrospectionException, IllegalAccessException,InvocationTargetException {PropertyDescriptor pd=new PropertyDescriptor(propertyName,refp.getClass());//创建对象关联Method methodGetX=pd.getReadMethod();//获取JavaBean类中的getX方法Object retval=methodGetX.invoke(refp);//调用getX方法return retval;}}
- 枚举、反射和内省总结
- 静态导入,枚举,反射,内省
- 反射和内省机制
- java 反射和内省
- 内省和自省 反射
- 反射和内省
- 内省和反射
- java反射和内省
- java反射和内省
- 反射和内省
- java反射和内省
- 反射和内省比较
- java反射和内省
- 内省和反射
- 反射和内省
- Java之反射、枚举、内省、注解
- 反射 (Reflection) 和内省 (Introspector)
- java的内省和反射
- Android动画之--translate笔记
- 转载: 广东省住房和城乡建设厅关于开展建筑信息模型BIM技术推广应用工作的通知
- Python标准库(非常经典的各种模块介绍)
- contentprovider的学习实例总结
- JavaScript-----prototype解析
- 枚举、反射和内省总结
- awk命令详解
- java操作 mongo DB 数据库例子
- C# 读取Excel文件代码
- linux下 libxml2 xml解析
- HTML5 聚光灯特效
- 注解、泛型和类加载器
- Java EE工程目录结构规范
- C# winfrom 窗体调用 WPF 窗体注意的事项