class,编程的基础
2016-07-27 23:23
155 查看
我们用了这么久的class,很少有人认真的去看过我们class源码,今天我们来看看Class能带给我们什么?
一 如何获取class实例:
方法一:通过类本身获取class实例:
二、获取类的完整结构
1.获取类的属性:
三 类加载机制
我们上面讲了类能给我带来什么,下面我们来说说java的类加载机制。类加载机制就是把类装入内存中。那么,到底是怎么实现的,我们来看下面这张图:
1. 加载过程:
java的源程序通过javac编译成.class文件,之后我们使用JVM类加载机制加载.class文件(ps:只有使用的时候才会加载),将此.class文件加载到内存之后就是一个运行时类,并存在缓存区,一个运行时类只加载一次。
2.JVM加载过程中产生三个层次的类加载器,分别为:系统类加载器,扩展类加载器,引导类加载器,具体我们看图:
现在存在这样一种情况,源码中可以获取到系统类加载器,扩展类加载器,但是不能获取到引导类加载器,因为引导类加载器是JVM的核心,所以我们无法获取:
四 总结:
有了类,才有了我们面向对象的概念,类给我们提供了很多我们想像不到的东西,好好挖掘吧!
一 如何获取class实例:
方法一:通过类本身获取class实例:
Class clazz1 = Person.class; System.out.println(clazz1.getName());方法二、通过运行时类来获取class实例:
Person p = new Person(); Class clazz3=p.getClass(); System.out.println(clazz3.getName());方法三、通过静态方法获取class实例:
Class clazz4=Class.forName("cn.dandan.test.Person"); System.out.println(clazz4.getName());方法四、通过类加载器获取class实例:
ClassLoader classLoader=this.getClass().getClassLoader(); Class clazz5= classLoader.loadClass("java.lang.String"); System.out.println(clazz5.getName());
二、获取类的完整结构
1.获取类的属性:
@Test public void test1(){ Class clazz1= Person.class; //只能获得运行类中与父类中生命为public 的属性 Field[] fields=clazz1.getFields(); for(int i=0;i<fields.length;i++){ System.out.println(fields[i]); } //可获得本类中所有生命的属性 Field[] fields1=clazz1.getDeclaredFields(); for(int i=0;i<fields1.length;i++){ System.out.println(fields1[i]); } }2.获取属性的名称类型及权限
//获取属性中各个部分的内容 @Test public void test2(){ Class clazz1= Person.class; //只能获得运行类中与父类中生命为public 的属性 Field[] fields=clazz1.getDeclaredFields(); for(Field f : fields){ //获取每个属性的权限修饰符 int i = f.getModifiers(); String str1 = Modifier.toString(i); System.out.println(str1+" "+f.getName()); //获取每个属性的变量类型 Class type =f.getType(); System.out.println(type); //获取每个属性的名称 /*System.out.println(f.getName());*/ System.out.println(); } }3.获取注释,修饰符,返回值类型,方法名,形参列表,异常等信息
@Test public void test3(){ Class clazz= Person.class; Method[] m2= clazz.getDeclaredMethods(); for(Method m:m2){ Annotation[] ann= m.getAnnotations(); for(Annotation a : ann){ //打印注解的方法 System.out.println(a); } //获得返回值的类型 String str= Modifier.toString(m.getModifiers()); System.out.println(str+" "); //形参列表 Class[] type=m.getParameterTypes(); for(int i=0;i<type.length;i++){ System.out.println(type[i].getName()+" args-"+i); } Class[] exception= m.getExceptionTypes(); for(int i=0;i<exception.length;i++){ System.out.println(exception[i].getName()); } /*System.out.println(m);*/ } }4.获取构造器
@SuppressWarnings("rawtypes") @Test public void test4() throws ClassNotFoundException{ String str= "cn.dandan.test.Person"; Class clazz= Class.forName(str); //1.获取构造器 Constructor[] constructor= clazz.getDeclaredConstructors(); // for(int i=0;i<constructor.length;i++){ System.out.println(constructor[i]); } //2.获取父类 Class superClass= clazz.getSuperclass(); System.out.println(superClass); //3.获取带泛型的父类 Type type=clazz.getGenericSuperclass(); System.out.println(type); }5.获取带泛型的父类:
@Test public void test5() throws ClassNotFoundException{ String str= "cn.dandan.test.Person"; Class clazz= Class.forName(str); Class superClass= clazz.getSuperclass(); Type type=clazz.getGenericSuperclass(); ParameterizedType paraType=(ParameterizedType)type; Type[] ars=paraType.getActualTypeArguments(); System.out.println(((Class)ars[0]).getName()); }6.获取父类的泛型:
@Test public void test5() throws ClassNotFoundException{ String str= "cn.dandan.test.Person"; Class clazz= Class.forName(str); Class superClass= clazz.getSuperclass(); Type type=clazz.getGenericSuperclass(); ParameterizedType paraType=(ParameterizedType)type; Type[] ars=paraType.getActualTypeArguments(); System.out.println(((Class)ars[0]).getName()); }7.获取实现的接口
@Test public void test6() throws ClassNotFoundException { String str= "cn.dandan.test.Person"; Class clazz= Class.forName(str); //获取所在的包 Package pack = clazz.getPackage(); System.out.println(pack); //获取接口 Class[] interfaces=clazz.getInterfaces(); for(int i=0;i<interfaces.length;i++){ System.out.println(interfaces[i]); } }
三 类加载机制
我们上面讲了类能给我带来什么,下面我们来说说java的类加载机制。类加载机制就是把类装入内存中。那么,到底是怎么实现的,我们来看下面这张图:
1. 加载过程:
java的源程序通过javac编译成.class文件,之后我们使用JVM类加载机制加载.class文件(ps:只有使用的时候才会加载),将此.class文件加载到内存之后就是一个运行时类,并存在缓存区,一个运行时类只加载一次。
2.JVM加载过程中产生三个层次的类加载器,分别为:系统类加载器,扩展类加载器,引导类加载器,具体我们看图:
现在存在这样一种情况,源码中可以获取到系统类加载器,扩展类加载器,但是不能获取到引导类加载器,因为引导类加载器是JVM的核心,所以我们无法获取:
@Test public void test5(){ ClassLoader classLoader1=ClassLoader.getSystemClassLoader(); //获取系统类 System.out.println(classLoader1); //获取扩展类 System.out.println(classLoader1.getParent()); //不能获取引导类 System.out.println(classLoader1.getParent().getParent()); }执行结果:
四 总结:
有了类,才有了我们面向对象的概念,类给我们提供了很多我们想像不到的东西,好好挖掘吧!
相关文章推荐
- hdoj5734 Acperience
- Eclipse 平台提供的扩展点
- struts2标签在js中的应用
- hdoj5742 It's All In The Mind
- php中echo/print/print_r()/var_dump()的区别
- hdoj4497
- 枚举与常量类的区别
- hdoj5428 The Factor
- 如何修改eclipse中maven默认仓库路径
- C#图片采集软件 自动翻页 自动分类(收集美图必备工具)(二)
- poj_2195Going Home(最小费用最大流)
- Numpy的ndarray简介
- 2016多校联训第二场 Keep On Movin hdoj5744
- eclipse Maven配置
- SpringMVC 重定向到其他系统的页面的两种方式
- Java ConcurrentModificationException异常原因和解决方法
- hdoj3791 二叉搜索树
- JAVA学习随笔(7)--Spring概述
- C++ 值传递、指针传递、引用传递详解
- 观察者模式-c++实现