黑马程序员---java基础加强训练,很经典
stringBuffer和stringBuilder的区别是,在多线程的stringbuilder的效率高,在多线程使用stringbuffer
flx@itcast.cn
java ee
ide --Itegrity development enviroment 集成开发环境
jms
jmx
jndi
享元模式 flyweight
有很多个小的对象,他们有很多属性相同,把他们变成一个对象,不同的属性,把他们变成方法的参数
成为外部状态,相同的参数称为内部状态
如果用抽象的方法来定义某个变量,就是将if else语句转成一个个独立的类
Class.forName("java.lang.string");
作用是返回字节码
1.类名.class 例如System.class获取字节码
2.对象 getclass() 例如 new Date().getClass()
3.Class.forName("java.lang.string");
只要在源程序中出现的类型,都有格子店 class实例对象 例如int[] void等等
反射就是java类中的各种成分映射成相应的java类
class.newInstance();
Field 提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段。
Array 允许在执行 get 或 set 访问操作期间进行扩展转换,但如果将发生收缩转换,则抛出一个 IllegalArgumentException
Method met=Class.forName(testname).getMethod("main", String[].class);
met.invoke(null,(Object)new String[]{"dfd","dd","ff","44"});
数组反射
//关于数组的反射
printArray(a2);//给一个string数组
printArray("anxianjie");//随便给一个字符串
private static void printArray(Object obj) {
if(obj.getClass().isArray())
{
int len=Array.getLength(obj);//通过array获取obj的长度
for(int x=0;x<len;x++)
{
System.out.println(Array.get(obj, x));// 返回指定数组对象中索引组件的值。
}
}else
System.out.println(obj);
}
===========
Object[] a=new Object[]{"dd",33,33,"dd"};
System.out.println( a[2].getClass().getName());
hashCode 的作用
1.当从hashset集合中查找对象时
java首先调用对象的hashCode方法获取的该对象的哈希码
,然后根据哈希码找到相应的存储区域,最后取出该
存储区域的每一个元素与该对象进行equals方法比较,这样就
不用遍历集合中的所有元素就可以得出结论,可见,hashset具有很好的
对象检索性能
2.防止内存泄漏,
内存泄漏就是,我打开某个东西,没有关掉,就这样日积月累就造成了内存泄漏
代码如下
package com.csdn.day1;
import java.util.Collection;
import java.util.HashSet;
public class hashCodeRef {
//这就是用反射技术开发框架的 原理
InputStream is=new FileInputStream("config.properties");//首先获取文件字节流
//通过类名获取类加载器,在通过类加载器获取绝对路径
//但是这种只能读,不能存取而上面那张可以存储数据
InputStream
is=hashCodeRef.class.getClassLoader().getResourceAsStream("com\\csdn\\day1\\config.properties");
Properties pro=new Properties();
pro.load(is);//用脑pro对象加载或取得 is流对象
is.close();
String classNamehashset=pro.getProperty("classNamehashset");
String classNamearraylist=pro.getProperty("classNamearraylist");
Collection coll=(Collection) Class.forName(classNamehashset).newInstance();//newInstance是调用不带参数的构造方法
// Collection coll=(Collection) Class.forName(classNamearraylist).newInstance();//newInstance是调用不带参数的构造方法
public static void main(String[] args) {
Collection coll=new HashSet();
ReflectPrint rp1=new ReflectPrint(3,4);
ReflectPrint rp2=new ReflectPrint(3,5);
ReflectPrint rp3=new ReflectPrint(3,4);
coll.add(rp1);
coll.add(rp2);
coll.add(rp3);
coll.add(rp1);
rp1.y=33;
coll.remove(rp1);
System.out.println(coll.size());
}
}
=============
package com.csdn.day1;
public class ReflectPrint {
private int x;
public int y;
public String str1="ball";
public String str2="basketball";
public String str3="heima";
public ReflectPrint(int x, int y) {
super();
this.x = x;
this.y = y;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ReflectPrint other = (ReflectPrint) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
@Override
public String toString()
{
return str1+"---"+str2+"----"+str3;
}
}
内省Introspectro
主要对javaBean进行操作,javabean是特殊的java类
Javabean的属性是根据set和get的方法名来推断出来的
PropertyDescriptor 描述 Java Bean 通过一对存储器方法导出的一个属性。 这是对javaBean简单的内省操作
package com.csdn.day1;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class IntorSpector {
/**
* @param args
*/
public static void main(String[] args)throws Exception {
ReflectPrint rp=new ReflectPrint(34, 5);
String propertyName="x";
PropertyDescriptor pd=new PropertyDescriptor(propertyName, rp.getClass());
Object retval = getproperty(rp, pd);
System.out.println(retval);
Object val=9;
setproperty(rp, pd, val);
System.out.println(rp.getX());
}
private static Object getproperty(Object rp, PropertyDescriptor pd)
throws IllegalAccessException, InvocationTargetException {
Method getx=pd.getReadMethod();
Object retval=getx.invoke(rp);
return retval;
}
private static void setproperty(Object rp, PropertyDescriptor pd,
Object val) throws IllegalAccessException,
InvocationTargetException {
Method setx=pd.getWriteMethod();
setx.invoke(rp, val);
}
}
BeanUtils的用法
package com.csdn.day1;
import java.beans.BeanDescriptor;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
public class IntorSpectorTest {
/**
* @param args
*/
public static void main(String[] args)throws Exception {
ReflectPrint rp=new ReflectPrint(34, 5);
String propertyName="x";
PropertyDescriptor pd=new PropertyDescriptor(propertyName, rp.getClass());//创建一个构造方法的属性符号
Object retval = getproperty(rp, pd);
System.out.println(retval);
Object val=9;
setproperty(rp, pd, val);
System.out.println(BeanUtils.getProperty(rp, "x").getClass().getName());
BeanUtils.setProperty(rp, "x", "55");
System.out.println(rp.getX());
BeanUtils.setProperty(rp, "brithday.time", "66");
System.out.println(BeanUtils.getProperty(rp, "brithday.time"));
PropertyUtils.setProperty(rp, "x",59);
System.out.println(PropertyUtils.getProperty(rp, "x").getClass().getName());
}
注解
Annotation
注解就相当于是一种标记,加了注解,就等于为程序打上了某种标记。没有加就等于每一某种标记以后,java编译器,开发工具和其他程序可以通过反射来你的类及各种元素上无任何标记,看你有什么标记,就去干相应的事,标记可以加载包,类,字段,方法的参数及局部变量上
注解的生命周期有三个阶段
1.Java源文件,
2.class文件,
3.内存中的字节码
自己定义注解 初级
package com.csdn.day2;
//@DscnAnnotation//这里必须要添加注解
@DscnAnnotation//这里必须要添加注解
public class AnnotationTest {
@SuppressWarnings("Deprecated")//这个注解是消除过时
public static void main(String[] args) {
// TODO Auto-generated method stub
System.runFinalizersOnExit(true);
// sayhua();
if(AnnotationTest.class.isAnnotationPresent(DscnAnnotation.class))//isAnnotationPresent判断是否是annotation所呈现 的
{
DscnAnnotation da=AnnotationTest.class.getAnnotation(DscnAnnotation.class);
System.out.println(da);
}
}
@Deprecated//这个注解表示这个方法已经过时但是还是可以用的,提醒开发者
public static void sayhua()
{
System.out.println("fdfdskf");
}
}
==================
package com.csdn.day2;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.lang.model.element.Element;
@Retention(RetentionPolicy.RUNTIME)//这句话就是说这个注解一直要保留到(runtime)运行期间
//@Target(ElementType.METHOD)
@Target(ElementType.TYPE) //这表示这个元注解用在任意类型上
public @interface DscnAnnotation {
}
注解类型有:数组,枚举,注解等等
泛型
Collection<string>和collection<object>这两个是没有转换关系的参数化类型
参数化类型是不考虑继承的
Collection<string> v=Collection<object>();//错误
Collection<object> v=Collection<string>();//也错误
这两种都没有错
Vector vector=new Vector<String>();
Vector<Object> v=vector;
使用?通配符可以引用其他各种参数化的类型,?定义类型主要作用是引用,可以调用与参数化无关的方法,不能调用与参数有关的方法
只有引用类型才能作为泛型的实际参数
在定义泛型是可以同时有多个类型的参数
如 T<K,V,S,DD> SH(K,V,S,DD)
泛型的参数类型推断是一个非常复杂的过程
<T>方法用了这个类型,那么返回值,就是这个类型
public static <T> T autoConvert(Object obj)
{
return (T)obj;
}
当一个变量本声明成泛型是只能被实例变量和方法调用,不能被静态方法和静态变量调用,因为静态成员是被所有参数化的类所调用,所以静态成员不应该有类级别的类型参数
拿到泛型的实际类型是一个高难度的知识点,可以通过反射
//通过反射来获取泛型的类型
Method method=GenericTest.class.getMethod("applyVector", Vector.class);
Type[] types=method.getGenericParameterTypes();//通过generictest的字节码来获取所有参数化的类型
ParameterizedType pType=(ParameterizedType) types[0];
System.out.println(pType.getActualTypeArguments()[0]);//通过ParameterizedType来获取这个泛型实际类型参数
System.out.println(pType.getRawType());
============
public static void applyVector(Vector<Date> ve)
{
}
类加载器
在java虚拟机中安装了多个类加载器,系统默认的三个类加载器,每个类负责加载特定位置的类;
Bootstrap,这个加载器不是java类
ExtClassLoader
AppClassLoader