点击打开链接 点击打开链接 点击打开链接 android培训、<a">点击打开链接 点击打开链接 java培训、期待与您交流!">点击打开链接 点击打开链接
Java程序中的各个java类属于同一类事物,描述这类事物的java类名就是Class。
Class类没有构造函数,不能new对象。怎么得到Class类的实例,有3中方法:
①类名.Class Class c1=Date.class;
②对象.getClass 获取对象所属的字节码 例:Person p=new Person; Class c2=p.getClass(),那么c2=Person.Class.
③静态方法:Class.forName(“完整的类名”),参数必须是完整类名,包名.类名。
Boolean / isPrimitive():是否表示一个基本类型的实例对象
Boolean /isArray():是否是数组类型的实例对象
Boolean / isInterface():是否是接口类型的实例对象
反射;就是把java类中的各种成分映射相应的java类。表示java类的Class类提供了一系列的方法,类获得其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是相应类(如Filed、Method、Contructor、Package等等)的实例对象来表示。
一个类中的每个成员都可用相应的反射API类的一个实例对象来表示,通过调用Class类的方法可以得到这些实例对象。
Constructor类:代表某个类中的一个构造方法。
得到某各类中所有构造方法:
Constructor[] cons=Class.forName(“java.lang.String”).getConStructors();
得到某一个构造方法
Constructor con = Class.forName (“java.lang.String”) .getConStructor(“StringBuffer.class”);
参数
创建实例对象
通常方式:String str=new String(new StringBuffer(“abc”));
反射方式:String str=(String)con.newInstance(new StringBuuffer(“abc”));
Class类也有newInstance()方法,它得到的是空参数的构造方法。
例:String str=(String)Class.forName(“java.lang.String”).newInstance().
Filed类:代表某个类中的一个成员变量
得到某个类的成员变量:
Field / getField(String name):返回指定公共字段。
Field[] / getFields():返回类或对象所有可能访问公共字段。
File / getDeclaredFiled(String name):返回指定字段,包括私有
Filed[] / getDeclaredFileds():返回所有字段。
Field方法:
Object / get(Object obj):返回指定对象上此Filed表示的字段的值。
Void / setAccessible(boolean flag):暴力反射
Class<?> / getType():得到此对象所表示字段的声明类型。
void / set(Object obj,Object value):将指定对象变量上此Field对象所表示的字段设置为指定的新值。
练习:将一个对象中的所有String类型的成员变量所对应的的字符串内容的a变成b.
Method类:代表某个类中的一个成员方法
得到某个类中的一个成员方法 Class类中的方法:
Method / getMethod(String name,Class<?>...parameterTypes);得到指定的公共成员的方法。parameterTypes表示要取得方法法的参数类型的字节码 。
Method[] / getMethods():返回此类的所有公共方法。
Method类中的方法:
Object invoke(Object obj,Object...args):运行obj对象的此类方法。如果传递的第一个参数为null,则表示该Method对应的是一个静态方法。
Invoke方法JDK1.4和JDK1.5版本的区别:
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(“str”,new Object[]{})的形式。
练习:用反射方式执行某个类中的main方法。
import java.lang.reflect.*; class MethodDemo { public static void main(String[] args) throws Exception { //获得ClassDemo1类的main方法。 Method me=ClassDemo1.class.getMethod("main",String[].class); //运行main方法 me.invoke(null,(Object)new String[]{}); //传递String类型数组给invoke方法, //必须强转Object,或者把String数组再封装成Object数组,这是JDK1.5新特性,传递 //一个数组参数给invoke,它会自动进行拆分,把数组里面的元素当做参数。 } }
Invoke方法JDK1.4和JDK1.5版本的区别:
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(“str”,new Object[]{})的形式。
Class类中的方法:Class<? super T> / getSuperclass():返回超类的Class。
String / getName():返回此Class对象所表示的实体名称。
数组的反射:具有相同维数数据类型相同的数组属于同一个类型,具有相同的Class实例对象。
代表数组的Class实例对象的getSuperClass()方法返回的父类为Object类对应的Class.
基本类型的一维数组可以被当做Object类型使用,不能当做Object[]类型使用;非基本类型的一维数组,既可以当做Object类型使用,又可以当做Object[]类型使用。
Array类:提供了动态创建和访问Java数组的方法
方法摘要:
Static object/get(Object array,int index):返回指定数组对象中索引组件的值
static boolean /getBoolean(Object obj,int index):以boolean形式返回值。
与此相似还有:getChar() getByte() getDouble() getFloat() getInt() getLong() getShort()
Static int / getlength(Object array):返回数组对象的长度。
Static Object / newInstance(Class<?> componentType,int length):创建一个具有指定的组件类型和长度的新数组。
Static void /newInstance(Class<?> componentType,int...dimensions):创建一个具有指定的组件类型和维度的新数组。
Static void / set(object array,int index,Object value):设置新值
Static void/ setBoolean(Object array,int index,boolean Z):将指定数组对象中索引组件的值设置为指定的boolean值。
与之相似的有:setByte() setChar() setDouble() setFloat() setInt() setLong() setShort()
import java.util.*; import java.lang.reflect.*; import java.<span style="color:#000000;">io</span>.*; class ReflectDemo { public static void main(String[] args) throws Exception { //创建流对象 InputStream is=new FileInputStream("prop.txt"); //创建Properties对象 Properties p=new Properties(); //Properties与流相关联 p.load(is); //利用反射取得配置文件中设置的类 Class clazz=Class.forName(p.getProperty("ClassName")); Collection<Person> h=(Collection<Person>)clazz.newInstance(); h.add(new Person("lisi",15)); h.add(new Person("lisi02",15)); h.add(new Person("lisi",15)); System.out.println(h.size()); } } class Person { private String name; private int age; Person(String name,int age) { this.name=name; this.age=age; } public String getName() { return name; } public int getAge() { return age; } public int hashCode() { return name.hashCode()+age*34; } public boolean equals(Object obj) { if(!(obj instanceof Person)) return false; Person p=(Person)obj; if(this.name.equals(p.getName())) return age==p.getAge(); return name.equals(p.getName()); } }
答:存在。Java中对象是采用new或者反射的方法创建的,这些对象的创建都是在堆(Heap)中分配的,所有对象的回收都是由Java虚拟机通过垃圾回收机制完成的。判断一个内存空间是否符合垃圾收集标准有两个:一个是给对象赋予了空值null,以下再没有调用过,另一个是给对象赋予了新值,这样重新分配了内存空间。在底层数据结构是哈希表的集合中,假如存入了一个对象,然后改变了对象与哈希值有关的属性,这个对象会重新分配内存空间,然后集合的引用地址值不会变,这个内存空间就不会被回收,同时集合无法对这个对象进行删除等的操作,因为地址值已经改变,造成内存泄露。另外造成内存泄露的原因可能有:
1、内部类和外部类的引用容易出现内存泄露的问题
2、监听器的使用,java中往往会使用到监听器,在释放对象的同时没有相应删除监听器的时候也可能导致内存泄露。
3、大量临时变量的使用,没有及时将对象设置为null也可能导致内存的泄露
4、数据库的连接没有关闭情况,包括连接池方法连接数据库,如果没有关闭ResultSet等也都可能出现内存泄露的问题。
举例一个内存泄露的例子:
Vector v = new Vector(10);
for (int i = 1; i<100; i++){
Object o = new Object();
v.add(o);
o = null;
}
别以为o对象被回收了,实际上v引用了这些对象,还被引用的对象GC是没有办法回收的,这样就很可能导致内存的泄露。
内省Introspector,主要用于对JavaBean类进行操作。JavaBean是一个特殊的Java类,主要用于传递数据信息。这种Java类中的方法主要用于访问私有的字段,且方法名称符合某种命名规则。
如果在两个模块之间传递多个信息,可以将这些信息封装到JavaBean中,这种JavaBean的实例对象通常称之为值对象(Value Object,简称VO),这些信息在类中用私有字段来存储,如果读取或设置这些字段的值,则需要通过一些相应的方法来访问,例如类A中有属性name,设置了getName,setName来得到其值或者设置新的值。通过getName/setName来访问name属性,这就是默认的规则。符合这类规则的类可以当做Java Bean来操作。
符合规则的类当做JavaBean操作的好处:
这里就要了解一个类PropertyDescriptor:
1.在java EE开发中,经常使用到JavaBean,很多环境就要求按JavaBean方式进行操作。
2.JDK中提供了对JavaBean操作的一些API,这套API就成为内省,用内省这套API操作JavaBean比用普通类的方式更方便。
内省中的类:
构造函数:PropertyDescriptor(String propertyName,Class<?> beanclass)
PropertyDescriptor(String propertyName,Class<?> beanclass,String readMethodName,String writeMethodName)
PropertyDescriptor(String propertyName,Method readMethod,Method writeMethod)
重要方法:
Method | getReadMethod():获得用于读取属性值的方法。
Method | getWriteMethod():获取用于写入属性值的方法。
void | setReadmethod(Method readMethod):设置应该用于读取属性值的方法。
void | setWriteMethod(Method writeMethod):设置应该用于写入属性值的方法。
String | getName():获得此特性的编程名称。
例:test JavaBeanDemo.java
import java.lang.reflect.*; class JavaBeanDemo { public static void main(String[] args) throws Exception { //创建一个符合JavaBean规则的A类对象 A a1=new A(); /* 把setter,getter方法后跟的属性名,不用管其变量名, 这例子中就是Name,如果第二个字母为小写,就把第一个字母也变成小写, 把属性名和a1的字节码对象传递给propertyDescriptor. */ PropertyDescriptor pd=new PropertyDescriptor("X",a1.getClass()); //propertyDescriptor类中的方法getReadMethod和setWriteMethod就可以得到a1的getter和setter方法。 Method readMethod=pd.getReadMethod(); Method writeMethod=pd.getWriteMethod(); //用到反射中Method类的invoke方法调用getter和setter方法。 writeMethod.invoke(a1,9); System.out.println(readMethod.invoke(a1)); } } //A类,符合JavaBean的规则 class A { private int x; public void setName(int x) { this.x=x; } public int getName() { return x; }
}
Introspector类:没有构造函数,不能创建对象,里面的方法都是静态的
重要方法:
static BeanInfo | getBeanInfo(class<?> beanClass):在JavaBean上进行内省,了解其所有属性、公开的方法和事件。
BeanInfo接口:
PropertyDescriptor[] |getPropertyDescriptors():返回受此bean支持的可编辑属性的propertyDescriptor数组。
例:通过Introspector与BeanInfo接口间接获得某JavaBean 类的PropertyDescriptor tesrt IntrDemo.java
import java.beans.*; import java.lang.reflect.*; class IntrDemo { public static void main(String[] args) throws Exception { A a1=new A(); //通过Introspector 和 BeanInfo间接得到类的所有属性、公开方法和事件。 BeanInfo bi=Introspector.getBeanInfo(A.class); PropertyDescriptor[] pds=bi.getPropertyDescriptors(); //因为得到的是组,所以要进行遍历,判断哪一个是想要的方法 for(PropertyDescriptor pd:pds) { if(pd.getName().equals("name")) { Method readMethod=pd.getReadMethod(); Method writeMethod=pd.getWriteMethod(); writeMethod.invoke(a1,9); System.out.println(readMethod.invoke(a1)); } } } } //A类,符合JavaBean的规则 class A { private int x; public void setName(int x) { this.x=x; } public int getName() { return x; } }
里面所有的方法都是静态,不用创建对象。
重要方法:
setProperty(对象,属性名,值的字符串)
getProperty(对象,属性名) 得到的是字符串
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/libin1127/article/details/47292711