反射机制笔记1

1、public abstract class ClassLoader extends Object

类加载器是负责加载类的对象。ClassLoader 类是一个抽象类。如果给定类的二进制名称,那么类加载器会试图查找或生成构成类定义的数据。一般策略是将名称转换为某个文件名,然后从文件系统读取该名称的“类文件”。

每个 Class 对象都包含一个对定义它的ClassLoader引用

数组类的 Class 对象不是由类加载器创建的,而是由 Java 运行时根据需要自动创建。数组类的类加载器由 Class.getClassLoader() 返回,该加载器与其元素类型的类加载器是相同的;如果该元素类型是基本类型,则该数组类没有类加载器。

应用程序需要实现 ClassLoader 的子类,以扩展 Java 虚拟机动态加载类的方式。

类加载器通常由安全管理器使用,用于指示安全域。

ClassLoader 类使用委托模型来搜索类和资源。每个ClassLoader 实例都有一个相关的父类加载器。需要查找类或资源时,ClassLoader 实例会在试图亲自查找类或资源之前,将搜索类或资源的任务委托给其父类加载器。虚拟机的内置类加载器(称为 "bootstrap class loader")本身没有父类加载器,但是可以将它用作ClassLoader 实例的父类加载器。 

2、jdk里面的ClassLoader到底有多少个?

bootstrap class loader:

最核心的类是被其load进来的,它是最早启动的class loader,是由操作系统本地语言来。这个class loader也没有名字,也拿不出来。

extension class loader:

它是jdk内置的,它负责jdk的扩展类。jdk的扩展类一般放在jre/lib/ext目录下面。
http://blog.csdn.net/xyang81/article/details/7292380

application class loader
以下图片摘自尚学堂马士兵老师java基础视频的ppt。




http://blog.csdn.net/yuebinghaoyuan/article/details/7244123(关于class类原理的简介)


浅谈Class类

http://www.cnblogs.com/bethunebtj/p/4680532.html(Java中Class类及其详解,站在巨人的肩膀上可以看得更远)

http://www.cnblogs.com/lzq198754/p/5780331.html(反射机制详解)

http://www.cnblogs.com/duanxz/p/3511695.html(Java序列化之serialVersionUID

1、首先我们要区分Class类和关键字class的区别。
2、 Java程序在运行时,Java运行时系统一直对所有的对象进行所谓的运行时类型标识,即所谓的RTTI。这项信息纪录了每个对象所属的类。虚拟机通常使用运行时类型信息选准正确方法去执行,用来保存这些类型信息的类是Class类。Class类封装一个对象和接口运行时的状态,当装载类时,Class类型的对象自动创建。
3、 Class类的对象内容是你创建的类的类型信息,比如你创建一个 shapes 类,那么,Java会生成一个内容是 shapes 的Class类的对象
4、 Class类的对象不能像普通类一样,以  new shapes()  的方式创建,它的对象只能由JVM创建,因为这个类没有public构造函数
5、Class类的作用是运行时提供或获得某个对象的类型信息,和C++中的typeid()函数类似。这些信息也可用于反射。

Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。
Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。

Class方法简介:

public String toString()
将对象转换为字符串。字符串的表示形式为字符串 " class" 或 "interface" 后面紧跟一个空格,然后是该类的完全限定名,它具有 getName 返回的那种格式。如果此 Class 对象表示一个基本类型,则此方法返回该基本类型的名称。如果该 Class 对象表示 void,则此方法返回 "void"。 
public static Class<?> forName(String className) throws ClassNotFoundException
返回与带有给定字符串名的类或接口相关联的 Class 对象
注意带上包名
public static Class<?> forName(String name,   boolean initialize,   ClassLoader loader)   throws ClassNotFoundException
使用给定的类加载器,返回与带有给定字符串名的类或接口相关联的Class 对象。(以getName 所返回的格式)给定一个类或接口的完全限定名,此方法会试图定位、加载和链接该类或接口。指定的类加载器用于加载该类或接口。如果参数loader 为 null,则该类通过引导类加载器加载。只有 initialize 参数为 true 且以前未被初始化时,才初始化该类。 
name - 所需类的完全限定名
initialize - 是否必须初始化类
loader - 用于加载类的类加载器  public T newInstance()  throws InstantiationException,  IllegalAccessException
创建此Class 对象所表示的类的一个新实例。如同用一个带有一个空参数列表的new 表达式实例化该类。如果该类尚未初始化,则初始化之。 
public boolean isInstance(Object obj)
判定指定的Object 是否与此Class 所表示的对象赋值兼容。此方法是 Java 语言instanceof 运算符的动态等效方法。如果指定的Object 参数非空,且能够在不引发 ClassCastException 的情况下被强制转换成该Class 对象所表示的引用类型,则返回 true,否则返回false。 
public boolean isAssignableFrom(Class<?> cls)
判定此Class 对象所表示的类或接口与指定的Class 参数所表示的类或接口是否相同,或是否是其超类或超接口。如果是则返回true,否则返回 false。如果该 Class 表示一个基本类型,且指定的Class 参数正是该Class 对象,则该方法返回true,否则返回false。 
public boolean isInterface()
判定指定的Class 对象是否表示一个接口。
public boolean isArray()
判定此Class 对象是否表示一个数组类。
public boolean isPrimitive()
判定指定的 Class 对象是否表示一个基本类型,有九种预定义的 Class 对象,表示八个基本类型和 void。这些类对象由 Java 虚拟机创建,与其表示的基本类型同名,即 booleanbytecharshortintlongfloatdouble。这些对象仅能通过下列声明为 public static final 的变量访问,也是使此方法返回 true 的仅有的几个 Class 对象。 public boolean isAnnotation()
http://blog.csdn.net/ideality_hunter/article/details/53128238(这是一篇关于注解的博客)
如果此Class 对象表示一个注释类型则返回 true。注意,如果此方法返回 true,则isInterface() 也返回 true,因为所有的注释类型同时也是接口。
public boolean isSynthetic()
如果此类是复合类,则返回true,否则false。 
(你是否不太清楚这个复合类,
1.基本数据类型:数值型、字符型、布尔型;
2.引用数据类型(复合类型):类、接口、数组。)
http://blog.csdn.net/feier7501/article/details/19088361(我在网上找了一篇关于此方法的博客,但还是有点不太懂,并且我也亲自试验了一下。)
public String getName()
String 的形式返回此 Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称。 
public ClassLoader getClassLoader()
返回该类的类加载器。有些实现可能使用 null 来表示引导类加载器。如果该类由引导类加载器加载,则此方法在这类实现中将返回 null。
public TypeVariable<Class<T>>[] getTypeParameters()
按声明顺序返回TypeVariable 对象的一个数组,这些对象表示用此GenericDeclaration 对象所表示的常规声明来声明的类型变量。如果基础的常规声明不声明类型变量,则返回长度为 0 的数组。
public Class<? super T> getSuperclass()
返回表示此Class 所表示的实体(类、接口、基本类型或 void)的超类的Class。如果此Class 表示Object 类、一个接口、一个基本类型或 void,则返回 null。如果此对象表示一个数组类,则返回表示该 Object 类的Class 对象。 
public Type getGenericSuperclass()
返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的直接超类的 Type。

如果超类是参数化类型,则返回的 Type 对象必须准确反映源代码中所使用的实际类型参数。如果以前未曾创建表示超类的参数化类型,则创建之。请参阅ParameterizedType 声明,了解参数化类型创建过程的语义。如果此Class 表示 Object 类、接口、基本类型或 void,则返回 null。如果此对象表示一个数组类,则返回表示 Object 类的Class 对象。 

public Package getPackage()
获取此类的包。此类的类加载器用于查找该包。如果该类是通过引导类加载器加载的,则搜索从 CLASSPATH 加载的包的集合,以查找该类的包。如果所有包对象都不是用该类的类加载器加载的,则返回 null。
public Class[] getInterfaces()
确定此对象所表示的类或接口实现的接口。就是看它实现了那些接口。
public Type[] getGenericInterfaces()
返回表示某些接口的Type,这些接口由此对象所表示的类或接口直接实现。 
public Class<?> getComponentType()
返回表示数组组件类型的Class。如果此类不表示数组类,则此方法返回 null
public int getModifiers()
返回此类或接口以整数编码的 Java 语言修饰符。修饰符由 Java 虚拟机的publicprotectedprivatefinalstaticabstractinterface 对应的常量组成;它们应当通过 Modifier 类的方法来解码。
package com.lanling;
import java.io.Serializable;
public class TestGeneric  extends People implements Serializable, Runnable {
	
	public static void main(String[] args) {
		Class<?> clzz=null;
		try {
			clzz=Class.forName("com.lanling.People");
		} catch (ClassNotFoundException e) {
			
			e.printStackTrace();
		}
		Class<? super TestGeneric> clzz2=(Class<? super TestGeneric>) clzz.getSuperclass();
		/*System.out.println(clzz2.getName()+","+clzz2.toString());
		Class<? super TestGeneric> clzz3=(Class<? super TestGeneric>) clzz.getGenericSuperclass();
		System.out.println(clzz2);
		System.out.println(clzz2.getPackage());
		System.out.println(clzz.getPackage());*/
		System.out.println(clzz.getModifiers());
		System.out.println(clzz2.getModifiers());
	}
	@Override
	public void run() {}
}
class People{
	private String name;
	private int age;
	public People(){		}
	public People(String name,int age){
		this.name=name;
		this.age=age;
	}
	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;
	}	
}运行结果为
0
1
public Object[] getSigners()
返回此类的标记,若无标记则返回 null。特别地,如果此对象表示一个基本类型或 void,则此方法返回 null
public Method getEnclosingMethod()
如果此 Class 对象表示某一方法中的一个本地或匿名类,则返回 Method 对象,它表示基础类的立即封闭方法。否则返回 null。 特别地,如果基础类是由一个类型声明、实例初始值设定项或静态初始值设定项立即封闭的本地或匿名类,则此方法返回 null。public Class<?> getDeclaringClass()
public Class<?> getEnclosingClass()
public String getSimpleName()
public String getCanonicalName()
public boolean isAnonymousClass()
public boolean isLocalClass()
当且仅当基础类是本地类时返回true。 
 Constructor<?>getEnclosingConstructor()
          如果该 Class 对象表示构造方法中的一个本地或匿名类,则返回Constructor 对象,它表示基础类的立即封闭构造方法。
 MethodgetEnclosingMethod()
          如果此 Class 对象表示某一方法中的一个本地或匿名类,则返回Method 对象,它表示基础类的立即封闭方法。
 T[]getEnumConstants()
          如果此 Class 对象不表示枚举类型,则返回枚举类的元素或 null。
 Constructor<T>getConstructor(Class... parameterTypes)
          返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。
 Constructor[]getConstructors()
          返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。
 MethodgetMethod(String name,Class... parameterTypes)
          返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。
 Method[]getMethods()
          返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共member 方法。
 TnewInstance()
          创建此 Class 对象所表示的类的一个新实例。
 StringtoString()
          将对象转换为字符串。

 ClassLoadergetClassLoader()
          返回该类的类加载器。

public T newInstance() throws InstatiationException,IllegalAccessException
Java 开发特别是 数据库 开发中,经常会用到Class.forName( )这个方法。通过查询 Java  Documentation我们会发现使用Class.forName( )静态方法的目的是为了动态加载类。在加载完成后,一般还要调用Class下的newInstance( )静态方法来实例化对象以便操作。因此,单单使用Class.forName( )是动态加载类是没有用的,其最终目的是为了实例化对象。

这里有必要提一下就是Class下的newInstance()和new有什么区别?,首先,newInstance( )是一个方法,而new是一个关键字,其次,Class下的newInstance()的使用有局限,因为它生成对象只能调用无参的构造函数,而使用new关键字生成对象没有这个限制。
好,到此为止,我们总结如下:
Class.forName("")返回的是类
Class.forName("").newInstance()返回的是object

Method类的invoke()方法





java中配置文件简介

当一个项目方到生产环境,开发人员不是会维护的有专门的维护人员,如果有些地方需要修改,维护人员更改配置文件重启ok了
如果在代码中呢?需要开发人员修改源码然后编译然后替换?你觉得哪个工作量大?而且更改配置文件改一个地方?但这个配置属性在代码中多处用到 如果去代码中岂不是要改很多地方?还有很多 优点自己慢慢感受吧
XML文件

xml是一种语言。这种语言编写的文件一般也是以xml结尾。你可以用记事本打开查看源码,或者用浏览器打开查看。它的内容都是由标签组成的,非常有规律。因为这种规律,才能快速的存取。一般用来存储配置信息,也有当数据库来用的。
配置文件和注解文件的优缺点

什么时候用xml
1.外部jar包依赖bean配置
2.用注解无法实现,或者用注解无法轻易实现的情形
3.项目组内部达成一致的约定的地方
4.特殊的配置(如:定义一个map)
优:容易编辑,配置比较集中,方便修改,在大业务量的系统里面,通过xml配置会方便后人理解整个系统的架构
缺:比较繁琐,类型不安全,配置形态丑陋,配置文件过多的时候难以管理
什么时候用注解
除了上面4点,其他情况都可以用
优:方便,简洁,配置信息和 Java 代码放在一起,有助于增强程序的内聚性。
缺:分散到各个class文件中,所以不宜维护




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值