当前位置: 编程技术>移动开发
本页文章导读:
▪Java温习八 Java复习八
从天津转站北京,爬到中关村到直立行走Java复习八Java基础加强的知识是我遇到最难的一部分,暂时无法消化得了,先过一遍,然后回过头来再看一遍……针对下载ppt来学习概念.........
▪ 开关机动画片及图片修改 开关机动画及图片修改
开机动画开关system/core/rootdir/etc/init.goldfish.sh setprop debug.sf.nobootanimation 0mediatek\custom\taibo13_gb\system\bootanim\bootanimationmediatek\custom\taibo13_gb\system\bootanim\shutanimation第一二张.........
▪ Java温习篇九 Java复习篇九
从天津转站北京,爬到中关村到直立行走Java复习篇九Web应用web页面Html:超文本标记语言。 Html语言中是由标签组成的。 Html中的数据都会封装在标签中,因为可以通过标签中的.........
[1]Java温习八
来源: 互联网 发布时间: 2014-02-18
Java复习八
从天津转站北京,爬到中关村到直立行走
Java复习八
Java基础加强的知识是我遇到最难的一部分,暂时无法消化得了,先过一遍,然后回过头来再看一遍……
针对下载ppt来学习
概念:
IDE:
1.泛型
import java.util.*;
/**
* 泛型
* @author xinglefly
* @version 1
*/
public class Generic {
public static void main(String[] args){
//jdk 1.5中几个类在定义集合时,明确比哦啊是你要集合中装那种类型的数据,无法加入指定类型以外的数据。
ArrayList collection = new ArrayList();
collection.add(1);
collection.add(1L);
collection.add("abc");
ArrayList<Integer> collection1 = new ArrayList<Integer>();
collection1.add(1);
// collection.add(1L);
// collection.add("abc");
//泛型是提供给javac编译器使用的,可以限定集合中的输入类型,让编译器挡住源程序中的非法输入,
//编译器编译带类型说明的集合时会去除“类型”信息,是程序允许那个效率不受影响,对于参数化的泛型类型,getClass()方法的返回值和原始类型完全一样。
//由于编译生成的字节码会去掉泛型的类型信息,只要能掉过编译器,就可以往某个泛型集合中加入其它类型数据,例如,用反射得到集合,再调用其add方法即可。
//参数化类型与原始类型的兼容性
Collection<String> c = new Vector();//参数化类型可以引用一个原始类型的对象,编译报告警告
Collection c1 = new Vector<String>();//原始类型可以应用给一个参数化类型的对象,编译警告
//参数化类型不考虑类型参数的继承关系:
// Vector<String> v = new Vector<Object>();//错误!
// Vector<Object> v1 = new Vecotr<String>;//错误
// Vector v2 = new Vector<String>();
/*限定通配符的上边界
* Vector<? extends Number> x = new Vector<Integer>();正确
* Vector<? extends Number> x = new Vector<String>(); 错误
*
* 限定通配符的下边界:
* Vector<? super Integer> x = new Vector<Number>();正确
* Vector<? super Integer> x = new Vector<Byte>();错误
*
* 提示: 限定通配符总是包括自己。
*/
HashMap<String,Integer> maps = new HashMap<String, Integer>();
maps.put("zhangsan", 22);
maps.put("lis", 23);
maps.put("wangwu", 28);
Set<Map.Entry<String, Integer>> entrySet = maps.entrySet();
for(Map.Entry<String, Integer> entry : entrySet){
System.out.println(entry.getKey()+" :: "+entry.getValue());
}
/*在jsp页面中哽咽经常要对Set或Map集合进行迭代
* <c:forEach items="${map}" var="entry">
* ${entry.key}:${entry.value}
* </c:forEach>
*/
/**用于放置泛型的类型参数的尖括号应出现在方法的其他所有修饰符之后和在方法的返回类型之前,就是紧邻返回值之前。
* 类型参数通常用单个大写字母白哦是。
* 只有引用类型才能作为泛型方法的实际参数,swap(new int[3],3,4);语句报告编译错误
* 除了在应用泛型是可以使用extends限定负,在定义泛型时也可以使用extends限定符。
* Class.getAnnotation()方法的定义,并且可以用&来制定多个边界,如<V extends Serializable & cloneable> void method(){}
*
* 普通方法、构造方法和静态方法中都可以使用泛型。编译器也不允许穿件类型变量的数组。
* 也可以用类型变量表示异常,称为参数化的遗产个,可以用于方法的throws列表中个,但是不能用于catch 字句中。
*
* 在泛型中更可以同时有多个类型参数,在定义他们的尖括弧中用逗号分,
* 如public static <K,V> v getValue(K key){return map.get(key);}
*/
/*类型参数的类型推断
* 编译器判断泛型方法的实际类型参数的过程称为类型推断,类型推断是相对于直觉推断的,其实现方法是一种非常复杂的过程。
* 根据调用泛型方法时实际传递的参数类型或返回值得类型来推断,具体 规则如下:
* 当某个类型变量只在整个参数李彪中的所有参数和返回值中的一处被应用,那么根据调用方法时该出的实际应用类型来确定,这
* 很容易凭着感觉凭着感觉推断出来,即直接根据调用方法时传递的参数类型或返回值来决定泛型参数的类型,
* 如:swap(new String[3],3,4)-->static <E> void swap(E[] a,int i,int j)
* 当某个类型变量在整个参数类中的所有参数和返回值中的多出被应用了,如果调用方法时这多处的实际应用类型都对应同一个种
* 类型都对应同一种类型来确定,这很容易凭着感觉推断出来,
* 如:add(3,5) -->static <T> T add(T a,T b)
* 当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法时这多处的实际应用类型对应到了不同的类型,
* 且没有使用返回值,这时候取多个参数中的最大交集类型,
* 下面语句实际对应的类型是Number,编译没问题,只是运行时出问题:
* 如: fill(new Integer[3],3,5f) -->static <T> void fill(T[] a,T v)
* 当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法时这多处的实际应用类型对应到了不同的类型,
* 并且使用返回值,这时候优先考虑返回值的类型,
*
*/
// copy1(new Vector<String>(),new String[10]);
// copy2(new Date[10],new String[10]);
}
private static <T> void fillArray(T[] a,T obj){
for(int i=0;i<a.length;i++){
a[i] = obj;
}
}
private static <T> T autoConbert(Object obj){
return (T)obj;
}
//交换数组的两个元素的位置
static <E> void swap(E[] a,int i,int j){
E t = a[i];
a[i] = a[j];
a[j] = t;
}
public static void printCollection(Collection<Object> cols){
for(Object obj : cols){
System.out.println(obj);
}
//cols.add("String");没错
// cols = new HashSet<Date>();//运行错误
cols.size();//没错的,此方法与类型参数没有关系
/*
* 总结:使用?通配符可以引用其他各种参数化得类型,?通配符定义的变量主要用作引用,
* 可以调用与参数化无关的方法,不能调用与参数化有关的方法。
*/
}
}
2.枚举
/**
* Enum
* 枚举:是一个类,每一个类都是一个对象。
* 就是要让某个类型的变量的取值只能为若干个固定值中的一个,负责,编译器就会报错。
* 枚举可以让编译器在编译时就可以控制源程序中填写的非法值,普通变量的方式在开发阶段无法实现这一目标
* @author xinglefly
* @version 1
*/
public abstract class WeekDay {
private WeekDay(){}
/* public final static WeekDay SUN = new WeekDay();
public final static WeekDay MON = new WeekDay();
*/ public final static WeekDay FRI = new WeekDay(){
public WeekDay nextDay1(){
return MON;
}
};
public final static WeekDay SUN = new WeekDay(){
public WeekDay nextDay1(){
return MON;
}
};
public final static WeekDay MON = new WeekDay(){
@Override
public WeekDay nextDay1() {
// TODO Auto-generated method stub
return SUN;
}
};
/*public WeekDay nextDay(){
if(this==SUN){
return MON;
}else{
return SUN;
}
}*/
public abstract WeekDay nextDay1();
public String toString(){
return this==SUN?"SUN":"MON";
}
}
public class EnumTest{
public static void main(String[] args){
WeekDay week = WeekDay.MON;
System.out.println(week.nextDay1());
WeekDay1 weekday = WeekDay1.FRI;
System.out.println(weekday);
System.out.println(weekday.name());
System.out.println(weekday.ordinal());
System.out.println(WeekDay1.valueOf("SUN").toString());
System.out.println(WeekDay1.values().length);
TraficLamp lamp = TraficLamp.RED;
System.out.println(lamp);
}
public enum WeekDay1{
SUN(1),MON(),TUE(),WED(),THI(),FRI(),SAT();
private WeekDay1(){System.out.println("first");}
private WeekDay1(int day){System.out.println("second");}
}
//枚举只有一个成员时,就可以作为一种单列的实现方式。
public enum TraficLamp{
RED(30){
public TraficLamp nextLamp(){
return GREEN;
}
},GREEN(45){
public TraficLamp nextLamp(){
return YELLOW;
}
},YELLOW(5){
public TraficLamp nextLamp(){
return RED;
}
};
public abstract TraficLamp nextLamp();
private int time;
TraficLamp(int time){
this.time=time;
}
};
}
反射
import java.lang.reflect.*;
import java.util.Arrays;
/**
* Reflect反射
* 反射就是把java类中的各种成分映射成相应的javav类。
* java程序中的各个java类属于同一类事物,描述这类事物的java类名就calss
* java类用于描述一类事物的共性,该类事物有什么属性,没什么属性,至于这个属性的值是什么,
* 则是由这个类的实例兑现过来确定的。不同的对象实例对象有不同的属性值。
* 一个类被类加载器加载到内存中,占用一片存储空间,这个空间里面的内容就是类的字节码,
* 不同类的字节码是不同的,所以他们在内存中的内容是不同的。这一个个的空间可分别用一个个的对象来表示,这些对象显然具有相同的类型。
* 表示java类的class类显然要提供一系列的方法,来获得其中的变量,方法,构造方法,修饰符,包等信息。这些信息就是用形影类的实例对象来表示,
* 它们是Field、Method、Construtor、Package等等。
* @author xinglefly
* @version 1
*/
public class ReflectTest {
public static void main(String[] args)throws Exception{
/*各个字节码对应的实例对象Class类型。
* 1.类名.class ,System.class
* 2.对象.getClass(),如,new Date().getClass()
* 3.Class.forName("类名"), 如,Class.forName("java.util.Date");
*
* 九个预定义Class实例对象。(8个基本类型+void.class())
* int.abc";
Class cls1 = str1.getClass();
Class cls2 = String.class;
Class cls3 = Class.forName("java.lang.String");
System.out.println(cls1==cls2);
System.out.println(cls1==cls3);
System.out.println(cls1.isPrimitive());//指定是否是一个基本类型
System.out.println(int.class.isPrimitive());
System.out.println(int.java.lang.String").getConstructors();
//得到某一个构造方法
Constructor constru = Class.forName("java.lang.String").getConstructor(StringBuffer.class);//获得方法时用到类型。
//创建实例对象
//通常方式
String str = new String(new StringBuffer("abc"));
//反射方式
String str3 = (String)constru.newInstance(new StringBuffer("abc"));
Constructor con1 = String.class.getConstructor(StringBuffer.class);
//Class.newInstance()方法:
//该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。
String str2 = (String)con1.newInstance(new StringBuffer("abc"));
System.out.println(str2.charAt(2));
ReflectPoint pt1 = new ReflectPoint(3,5);
Field fieldY = pt1.getClass().getField("y");
//fieldY的值是多少?是5,错!field不是对象身上的变量,而是类上,
System.out.println(fieldY.get(pt1));
//对私有属性
Field fieldX = pt1.getClass().getDeclaredField("x");
fieldX.setAccessible(true);
System.out.println(fieldX.get(pt1));
changeStringValue(pt1);
System.out.println(pt1);
/*Method类代表某个类中的成员
*
*/
//得到某个类的方法
// Method charAt = Class.forName("java.lang.String").getMethod("charat", int.class);
//调用方法
//通常方式:System.out.println(str.charAt(1));
//反射方式: System.out.println(charAt.invoke(str,1));
//如果传递给Method对象的invoke()方法的第一个参数为null,意味着该method对象对应的是一个静态方法!
// new String[]{new String("abc"),new String("xyz"),new String("123")};
Method methodCharAt = String.class.getMethod("charAt", int.class);
System.out.println(methodCharAt.invoke(str1, 1));
System.out.println(methodCharAt.invoke(str1, new Object[]{2}));
String startingClassName = args[0];
Method mainMethod = Class.forName(startingClassName).getMethod("main",String[].class);
mainMethod.invoke(null, new Object[]{new String[]{"111","222","333"}});
/*数组反射
* 具有相同维数和元素类型的数组属于同一个类型,即具有相同的class实例对象。
* 代表数组的Class实例对象的getSuperClass()方法返回的父类为Object类对应的class
* 基本类型的一维数组可以被当做Object类型使用,不能当做object[]类型使用;
* 非基本类型的一维数组,即可以当做Ojbect[]类型使用,又可以当做Object[]类型使用。
*/
int [] a1 = new int[]{1,2,3};
int [] a2 = new int[4];
int [][] a3 = new int[2][3];
String[] a4 = new String[]{"a","b","c"};
sop(a1.getClass() == a2.getClass());
// sop(a1.getClass() == a4.getClass());
// sop(a1.getClass() == a3.getClass());
sop(a1.getClass().getName());
sop(a1.getClass().getSuperclass().getName());
sop(a4.getClass().getSuperclass().getName());
sop(Arrays.asList(a1));
sop(Arrays.asList(a4));
printObject(a4);
printObject("xyz");
}
public static void printObject(Object obj){
Class clazz = obj.getClass();
if(clazz.isArray()){
int len = Array.getLength(obj);
for(int i=0;i<len;i++){
sop(Array.get(obj, i));
}
}else{
sop(obj);
}
}
//替换文件中的字节
private static void changeStringValue(Object obj)throws Exception{
Field[] fields = obj.getClass().getFields();
System.out.println(fields);
for(Field field : fields){
//因为是同一个字节码的比较用==
//if(field.getType().equals(String.class)){
if(field.getType() == String.class){
String oldValue = (String)field.get(obj);
String newValue = oldValue.replace('b', 'a');
field.set(obj, newValue);
}
}
}
public static void sop(Object obj){
System.out.println(obj);
}
}
class TestArguments{
public static void main(String[] args){
for(String arg : args){
System.out.println(arg);
}
}
}
JavaBean
**
* JavaBean 是一种特殊的java类,主要用于传递数据信息,这种java类中的主方法主要用于访问私有的字段,且方法名符合某种命名规则。
* 如果要在练个模块之间出点多个信息,可以将这些信息封装到一个javabean中,这种JavaBean的实例对象通常称为值对象(Value-Object,简称VO)
* 这些信息在类中用私有字段来存储,如果读取或设置这些字段的值,则需要通过一些相应的方法来访问。
*
* 总之,一个类被当做javaBean使用时,javaBean的属性是根据方法名推断处出来的,它根本看不到java类内部的成员变量。
* @author xinglefly
* @version 1
*/
public class IntroSpectorTest {
/* 一个符合javabean特点的类可以当做普通类一样进行使用个,但它当javabean用肯定需要带来一些额外的好处,我们才会去了解和应用javabean!
* 好处: 在java EE开发中,经常要使用到javabean.很多环境就要求按JavaBean方式进行操作,别人都这么用和要求这么做,那你就没什么挑选的余地。
* JDK中提供了对javabean进行操作的一些API,这套API就称为内省。如果要你自己去通过getX方法来访问私有的X,用省这套api操作JavaBean比用普通类的方式更方便。
*/
public static void main(String[] args)throws Exception{
ReflectPoint pt1 = new ReflectPoint(3,5);
String propertyName = "x";
//"x"-->"X"---"getX"-->MethodGetX-->
PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt1.getClass());
Method methodGetX = pd.getReadMethod();
Object retVal = methodGetX.invoke(pt1);
System.out.println(retVal);
/*Method methodSetX = pd.getWriteMethod();
methodSetX.invoke(pt1, 7);
System.out.println(pt1.getX());
*/
Object value = 8;
setProperties(pt1,propertyName,value);
System.out.println(getProperty(pt1,propertyName));
/*JDK 1.7的新特性
* Map map = (name:"zxx",age:18)
* BeanUtils.setProperty(map,"name","1hm");
*/
//出错
BeanUtils.setProperty(pt1, "birthday.time", "111");
System.out.println(BeanUtils.getProperty(pt1, "birthday.time"));
// PropertyUtils.setProperty(pt1, "x", 9);
}
public static void setProperties(Object pt1,String propertyName,Object value)throws Exception{
PropertyDescriptor pd2 = new PropertyDescriptor(propertyName,pt1.getClass());
Method methodSetX = pd2.getWriteMethod();
methodSetX.invoke(pt1, value);
}
/*采用遍历BeanInfo的所有属性方式来查找和设置某个RefectPoint对象的X属性。在程序中把一个类当做
* JavaBean来看,就是调用IntroSpector.getBeanInfo方法,得到的BeanInfo对象封装了把这个类当做JavaBean看的结果信息。
*
*/
private static Object getProperty(Object pt1,String propertyName)throws Exception{
/*PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt1.getClass());
Method methodGetX = pd.getReadMethod();
Object retVal = methodGetX.invoke(pt1);*/
BeanInfo beaninfo = Introspector.getBeanInfo(pt1.getClass());
PropertyDescriptor[] pds = beaninfo.getPropertyDescriptors();
Object retVal = null;
for(PropertyDescriptor pd : pds){
if(pd.getName().equals(propertyName)){
Method methodGetX = pd.getReadMethod();
retVal = methodGetX.invoke(pt1);
break;
}
}
return retVal;
}
}
5.加载器
用eclipse的打包工具将ClassLoaderTest输出成jre/lib/ext目录下的itcast.jar包,再在eclipse中运行这个类,运行结果显示为ExtClassLoader.此时的环境状态是classpath目录有ClassLoaderTest.class,ext/itcast.jar包中也有ClassLoaderTest.class,这时候我们就需要了解加载的具体过程和原理了。
类加载器的委托机制
当Java虚拟机要加载一个类时,到底派出那个类加载器去加载呢?
首先当前线程的类加载器去加载线程中的第一个类。
如果类A中引用了类B,java虚拟机将使用加载类的A的类加载器来加载类B.
还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类。
每个类加载器加载时,又先委托给其上级类加载器。
当所有祖宗类加载器没有加载到类,回到发起者类加载器,还加载不了,则抛ClassNotFountdException,不是再去找发起者类加载器的儿子,因为没有getChild方法,即使有,那么多儿子,找哪一个呢?
对着类加载器的参差结构图和委托加载原理,解释先前将ClassLoaderTest输出成jre/lib/ext目录下的itcast.jar包中后,运行结果为ExtClassLoader的原因。
编写自己的类加载器
自定义的类加载器的必须继承ClassLoader
loadClass方法与findClass方法
defineClass方法
编程步骤:
编写一个对文件内容进行简单加密的程序。
编写了一个自己的类装载器,可实现对加密过的类进行装载和解密。
编写一个程序调用类加载器加载类,在源程序中不能用该类名定义引用变量,因为编译器无法识别这个类。程序中可以除了使用ClassLoader.load方法之外,还可以使用设置线程的上下文类加载器或者系统类加载器,然后再使用Class.forName。
实验步骤:
对不带包名的class文件进行加密,加密结果存放到另外一个目录,例如: java MyClassLoader MyTest.class F:\itcast
运行加载类的程序,结果能够被正常加载,但打印出来的类装载器名称为AppClassLoader:java MyClassLoader MyTest F:\itcast
用加密后的类文件替换CLASSPATH环境下的类文件,再执行上一步操作就出问题了,错误说明是AppClassLoader类装载器装载失败。
删除CLASSPATH环境下的类文件,再执行上一步操作就没问题了。
代理的概念与作用
程序中的代理
要为已存在的多个具有相同接口的目标类的各个方法增加一些系统功能,例如,异常处理、日志、计算方法的运行时间、事务管理、等等,你准备如何做?
编写一个与目标类具有相同接口的代理类,代理类的每个方法调用目标类的相同方法,并在调用方法时加上系统功能的代码。 (参看下页的原理图)
如果采用工厂模式和配置文件的方式进行管理,则不需要修改客户端程序,在配置文件中配置是使用目标类、还是代理类,这样以后很容易切换,譬如,想要日志功能时就配置代理类,否则配置目标类,这样,增加系统功能很容易,以后运行一段时间后,又想去掉系统功能也很容易。
动态代理技术
要为系统中的各种接口的类增加代理功能,那将需要太多的代理类,全部采用静态代理方式,将是一件非常麻烦的事情!写成百上千个代理类,是不是太累!
JVM可以在运行期动态生成出类的字节码,这种动态生成的类往往被用作代理类,即动态代理类。
JVM生成的动态类必须实现一个或多个接口,所以,JVM生成的动态类只能用作具有相同接口的目标类的代理。
CGLIB库可以动态生成一个类的子类,一个类的子类也可以用作该类的代理,所以,如果要为一个没有实现接口的类生成动态代理类,那么可以使用CGLIB库。
代理类的各个方法中通常除了要调用目标的相应方法和对外返回目标返回的结果外,还可以在代理方法中的如下四个位置加上系统功能代码:
1.在调用目标方法之前
2.在调用目标方法之后
3.在调用目标方法前后
4.在处理目标方法异常的catch块中
从天津转站北京,爬到中关村到直立行走
Java复习八
Java基础加强的知识是我遇到最难的一部分,暂时无法消化得了,先过一遍,然后回过头来再看一遍……
针对下载ppt来学习
概念:
IDE:
1.泛型
import java.util.*;
/**
* 泛型
* @author xinglefly
* @version 1
*/
public class Generic {
public static void main(String[] args){
//jdk 1.5中几个类在定义集合时,明确比哦啊是你要集合中装那种类型的数据,无法加入指定类型以外的数据。
ArrayList collection = new ArrayList();
collection.add(1);
collection.add(1L);
collection.add("abc");
ArrayList<Integer> collection1 = new ArrayList<Integer>();
collection1.add(1);
// collection.add(1L);
// collection.add("abc");
//泛型是提供给javac编译器使用的,可以限定集合中的输入类型,让编译器挡住源程序中的非法输入,
//编译器编译带类型说明的集合时会去除“类型”信息,是程序允许那个效率不受影响,对于参数化的泛型类型,getClass()方法的返回值和原始类型完全一样。
//由于编译生成的字节码会去掉泛型的类型信息,只要能掉过编译器,就可以往某个泛型集合中加入其它类型数据,例如,用反射得到集合,再调用其add方法即可。
//参数化类型与原始类型的兼容性
Collection<String> c = new Vector();//参数化类型可以引用一个原始类型的对象,编译报告警告
Collection c1 = new Vector<String>();//原始类型可以应用给一个参数化类型的对象,编译警告
//参数化类型不考虑类型参数的继承关系:
// Vector<String> v = new Vector<Object>();//错误!
// Vector<Object> v1 = new Vecotr<String>;//错误
// Vector v2 = new Vector<String>();
/*限定通配符的上边界
* Vector<? extends Number> x = new Vector<Integer>();正确
* Vector<? extends Number> x = new Vector<String>(); 错误
*
* 限定通配符的下边界:
* Vector<? super Integer> x = new Vector<Number>();正确
* Vector<? super Integer> x = new Vector<Byte>();错误
*
* 提示: 限定通配符总是包括自己。
*/
HashMap<String,Integer> maps = new HashMap<String, Integer>();
maps.put("zhangsan", 22);
maps.put("lis", 23);
maps.put("wangwu", 28);
Set<Map.Entry<String, Integer>> entrySet = maps.entrySet();
for(Map.Entry<String, Integer> entry : entrySet){
System.out.println(entry.getKey()+" :: "+entry.getValue());
}
/*在jsp页面中哽咽经常要对Set或Map集合进行迭代
* <c:forEach items="${map}" var="entry">
* ${entry.key}:${entry.value}
* </c:forEach>
*/
/**用于放置泛型的类型参数的尖括号应出现在方法的其他所有修饰符之后和在方法的返回类型之前,就是紧邻返回值之前。
* 类型参数通常用单个大写字母白哦是。
* 只有引用类型才能作为泛型方法的实际参数,swap(new int[3],3,4);语句报告编译错误
* 除了在应用泛型是可以使用extends限定负,在定义泛型时也可以使用extends限定符。
* Class.getAnnotation()方法的定义,并且可以用&来制定多个边界,如<V extends Serializable & cloneable> void method(){}
*
* 普通方法、构造方法和静态方法中都可以使用泛型。编译器也不允许穿件类型变量的数组。
* 也可以用类型变量表示异常,称为参数化的遗产个,可以用于方法的throws列表中个,但是不能用于catch 字句中。
*
* 在泛型中更可以同时有多个类型参数,在定义他们的尖括弧中用逗号分,
* 如public static <K,V> v getValue(K key){return map.get(key);}
*/
/*类型参数的类型推断
* 编译器判断泛型方法的实际类型参数的过程称为类型推断,类型推断是相对于直觉推断的,其实现方法是一种非常复杂的过程。
* 根据调用泛型方法时实际传递的参数类型或返回值得类型来推断,具体 规则如下:
* 当某个类型变量只在整个参数李彪中的所有参数和返回值中的一处被应用,那么根据调用方法时该出的实际应用类型来确定,这
* 很容易凭着感觉凭着感觉推断出来,即直接根据调用方法时传递的参数类型或返回值来决定泛型参数的类型,
* 如:swap(new String[3],3,4)-->static <E> void swap(E[] a,int i,int j)
* 当某个类型变量在整个参数类中的所有参数和返回值中的多出被应用了,如果调用方法时这多处的实际应用类型都对应同一个种
* 类型都对应同一种类型来确定,这很容易凭着感觉推断出来,
* 如:add(3,5) -->static <T> T add(T a,T b)
* 当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法时这多处的实际应用类型对应到了不同的类型,
* 且没有使用返回值,这时候取多个参数中的最大交集类型,
* 下面语句实际对应的类型是Number,编译没问题,只是运行时出问题:
* 如: fill(new Integer[3],3,5f) -->static <T> void fill(T[] a,T v)
* 当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法时这多处的实际应用类型对应到了不同的类型,
* 并且使用返回值,这时候优先考虑返回值的类型,
*
*/
// copy1(new Vector<String>(),new String[10]);
// copy2(new Date[10],new String[10]);
}
private static <T> void fillArray(T[] a,T obj){
for(int i=0;i<a.length;i++){
a[i] = obj;
}
}
private static <T> T autoConbert(Object obj){
return (T)obj;
}
//交换数组的两个元素的位置
static <E> void swap(E[] a,int i,int j){
E t = a[i];
a[i] = a[j];
a[j] = t;
}
public static void printCollection(Collection<Object> cols){
for(Object obj : cols){
System.out.println(obj);
}
//cols.add("String");没错
// cols = new HashSet<Date>();//运行错误
cols.size();//没错的,此方法与类型参数没有关系
/*
* 总结:使用?通配符可以引用其他各种参数化得类型,?通配符定义的变量主要用作引用,
* 可以调用与参数化无关的方法,不能调用与参数化有关的方法。
*/
}
}
2.枚举
/**
* Enum
* 枚举:是一个类,每一个类都是一个对象。
* 就是要让某个类型的变量的取值只能为若干个固定值中的一个,负责,编译器就会报错。
* 枚举可以让编译器在编译时就可以控制源程序中填写的非法值,普通变量的方式在开发阶段无法实现这一目标
* @author xinglefly
* @version 1
*/
public abstract class WeekDay {
private WeekDay(){}
/* public final static WeekDay SUN = new WeekDay();
public final static WeekDay MON = new WeekDay();
*/ public final static WeekDay FRI = new WeekDay(){
public WeekDay nextDay1(){
return MON;
}
};
public final static WeekDay SUN = new WeekDay(){
public WeekDay nextDay1(){
return MON;
}
};
public final static WeekDay MON = new WeekDay(){
@Override
public WeekDay nextDay1() {
// TODO Auto-generated method stub
return SUN;
}
};
/*public WeekDay nextDay(){
if(this==SUN){
return MON;
}else{
return SUN;
}
}*/
public abstract WeekDay nextDay1();
public String toString(){
return this==SUN?"SUN":"MON";
}
}
public class EnumTest{
public static void main(String[] args){
WeekDay week = WeekDay.MON;
System.out.println(week.nextDay1());
WeekDay1 weekday = WeekDay1.FRI;
System.out.println(weekday);
System.out.println(weekday.name());
System.out.println(weekday.ordinal());
System.out.println(WeekDay1.valueOf("SUN").toString());
System.out.println(WeekDay1.values().length);
TraficLamp lamp = TraficLamp.RED;
System.out.println(lamp);
}
public enum WeekDay1{
SUN(1),MON(),TUE(),WED(),THI(),FRI(),SAT();
private WeekDay1(){System.out.println("first");}
private WeekDay1(int day){System.out.println("second");}
}
//枚举只有一个成员时,就可以作为一种单列的实现方式。
public enum TraficLamp{
RED(30){
public TraficLamp nextLamp(){
return GREEN;
}
},GREEN(45){
public TraficLamp nextLamp(){
return YELLOW;
}
},YELLOW(5){
public TraficLamp nextLamp(){
return RED;
}
};
public abstract TraficLamp nextLamp();
private int time;
TraficLamp(int time){
this.time=time;
}
};
}
反射
import java.lang.reflect.*;
import java.util.Arrays;
/**
* Reflect反射
* 反射就是把java类中的各种成分映射成相应的javav类。
* java程序中的各个java类属于同一类事物,描述这类事物的java类名就calss
* java类用于描述一类事物的共性,该类事物有什么属性,没什么属性,至于这个属性的值是什么,
* 则是由这个类的实例兑现过来确定的。不同的对象实例对象有不同的属性值。
* 一个类被类加载器加载到内存中,占用一片存储空间,这个空间里面的内容就是类的字节码,
* 不同类的字节码是不同的,所以他们在内存中的内容是不同的。这一个个的空间可分别用一个个的对象来表示,这些对象显然具有相同的类型。
* 表示java类的class类显然要提供一系列的方法,来获得其中的变量,方法,构造方法,修饰符,包等信息。这些信息就是用形影类的实例对象来表示,
* 它们是Field、Method、Construtor、Package等等。
* @author xinglefly
* @version 1
*/
public class ReflectTest {
public static void main(String[] args)throws Exception{
/*各个字节码对应的实例对象Class类型。
* 1.类名.class ,System.class
* 2.对象.getClass(),如,new Date().getClass()
* 3.Class.forName("类名"), 如,Class.forName("java.util.Date");
*
* 九个预定义Class实例对象。(8个基本类型+void.class())
* int.abc";
Class cls1 = str1.getClass();
Class cls2 = String.class;
Class cls3 = Class.forName("java.lang.String");
System.out.println(cls1==cls2);
System.out.println(cls1==cls3);
System.out.println(cls1.isPrimitive());//指定是否是一个基本类型
System.out.println(int.class.isPrimitive());
System.out.println(int.java.lang.String").getConstructors();
//得到某一个构造方法
Constructor constru = Class.forName("java.lang.String").getConstructor(StringBuffer.class);//获得方法时用到类型。
//创建实例对象
//通常方式
String str = new String(new StringBuffer("abc"));
//反射方式
String str3 = (String)constru.newInstance(new StringBuffer("abc"));
Constructor con1 = String.class.getConstructor(StringBuffer.class);
//Class.newInstance()方法:
//该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。
String str2 = (String)con1.newInstance(new StringBuffer("abc"));
System.out.println(str2.charAt(2));
ReflectPoint pt1 = new ReflectPoint(3,5);
Field fieldY = pt1.getClass().getField("y");
//fieldY的值是多少?是5,错!field不是对象身上的变量,而是类上,
System.out.println(fieldY.get(pt1));
//对私有属性
Field fieldX = pt1.getClass().getDeclaredField("x");
fieldX.setAccessible(true);
System.out.println(fieldX.get(pt1));
changeStringValue(pt1);
System.out.println(pt1);
/*Method类代表某个类中的成员
*
*/
//得到某个类的方法
// Method charAt = Class.forName("java.lang.String").getMethod("charat", int.class);
//调用方法
//通常方式:System.out.println(str.charAt(1));
//反射方式: System.out.println(charAt.invoke(str,1));
//如果传递给Method对象的invoke()方法的第一个参数为null,意味着该method对象对应的是一个静态方法!
// new String[]{new String("abc"),new String("xyz"),new String("123")};
Method methodCharAt = String.class.getMethod("charAt", int.class);
System.out.println(methodCharAt.invoke(str1, 1));
System.out.println(methodCharAt.invoke(str1, new Object[]{2}));
String startingClassName = args[0];
Method mainMethod = Class.forName(startingClassName).getMethod("main",String[].class);
mainMethod.invoke(null, new Object[]{new String[]{"111","222","333"}});
/*数组反射
* 具有相同维数和元素类型的数组属于同一个类型,即具有相同的class实例对象。
* 代表数组的Class实例对象的getSuperClass()方法返回的父类为Object类对应的class
* 基本类型的一维数组可以被当做Object类型使用,不能当做object[]类型使用;
* 非基本类型的一维数组,即可以当做Ojbect[]类型使用,又可以当做Object[]类型使用。
*/
int [] a1 = new int[]{1,2,3};
int [] a2 = new int[4];
int [][] a3 = new int[2][3];
String[] a4 = new String[]{"a","b","c"};
sop(a1.getClass() == a2.getClass());
// sop(a1.getClass() == a4.getClass());
// sop(a1.getClass() == a3.getClass());
sop(a1.getClass().getName());
sop(a1.getClass().getSuperclass().getName());
sop(a4.getClass().getSuperclass().getName());
sop(Arrays.asList(a1));
sop(Arrays.asList(a4));
printObject(a4);
printObject("xyz");
}
public static void printObject(Object obj){
Class clazz = obj.getClass();
if(clazz.isArray()){
int len = Array.getLength(obj);
for(int i=0;i<len;i++){
sop(Array.get(obj, i));
}
}else{
sop(obj);
}
}
//替换文件中的字节
private static void changeStringValue(Object obj)throws Exception{
Field[] fields = obj.getClass().getFields();
System.out.println(fields);
for(Field field : fields){
//因为是同一个字节码的比较用==
//if(field.getType().equals(String.class)){
if(field.getType() == String.class){
String oldValue = (String)field.get(obj);
String newValue = oldValue.replace('b', 'a');
field.set(obj, newValue);
}
}
}
public static void sop(Object obj){
System.out.println(obj);
}
}
class TestArguments{
public static void main(String[] args){
for(String arg : args){
System.out.println(arg);
}
}
}
JavaBean
**
* JavaBean 是一种特殊的java类,主要用于传递数据信息,这种java类中的主方法主要用于访问私有的字段,且方法名符合某种命名规则。
* 如果要在练个模块之间出点多个信息,可以将这些信息封装到一个javabean中,这种JavaBean的实例对象通常称为值对象(Value-Object,简称VO)
* 这些信息在类中用私有字段来存储,如果读取或设置这些字段的值,则需要通过一些相应的方法来访问。
*
* 总之,一个类被当做javaBean使用时,javaBean的属性是根据方法名推断处出来的,它根本看不到java类内部的成员变量。
* @author xinglefly
* @version 1
*/
public class IntroSpectorTest {
/* 一个符合javabean特点的类可以当做普通类一样进行使用个,但它当javabean用肯定需要带来一些额外的好处,我们才会去了解和应用javabean!
* 好处: 在java EE开发中,经常要使用到javabean.很多环境就要求按JavaBean方式进行操作,别人都这么用和要求这么做,那你就没什么挑选的余地。
* JDK中提供了对javabean进行操作的一些API,这套API就称为内省。如果要你自己去通过getX方法来访问私有的X,用省这套api操作JavaBean比用普通类的方式更方便。
*/
public static void main(String[] args)throws Exception{
ReflectPoint pt1 = new ReflectPoint(3,5);
String propertyName = "x";
//"x"-->"X"---"getX"-->MethodGetX-->
PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt1.getClass());
Method methodGetX = pd.getReadMethod();
Object retVal = methodGetX.invoke(pt1);
System.out.println(retVal);
/*Method methodSetX = pd.getWriteMethod();
methodSetX.invoke(pt1, 7);
System.out.println(pt1.getX());
*/
Object value = 8;
setProperties(pt1,propertyName,value);
System.out.println(getProperty(pt1,propertyName));
/*JDK 1.7的新特性
* Map map = (name:"zxx",age:18)
* BeanUtils.setProperty(map,"name","1hm");
*/
//出错
BeanUtils.setProperty(pt1, "birthday.time", "111");
System.out.println(BeanUtils.getProperty(pt1, "birthday.time"));
// PropertyUtils.setProperty(pt1, "x", 9);
}
public static void setProperties(Object pt1,String propertyName,Object value)throws Exception{
PropertyDescriptor pd2 = new PropertyDescriptor(propertyName,pt1.getClass());
Method methodSetX = pd2.getWriteMethod();
methodSetX.invoke(pt1, value);
}
/*采用遍历BeanInfo的所有属性方式来查找和设置某个RefectPoint对象的X属性。在程序中把一个类当做
* JavaBean来看,就是调用IntroSpector.getBeanInfo方法,得到的BeanInfo对象封装了把这个类当做JavaBean看的结果信息。
*
*/
private static Object getProperty(Object pt1,String propertyName)throws Exception{
/*PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt1.getClass());
Method methodGetX = pd.getReadMethod();
Object retVal = methodGetX.invoke(pt1);*/
BeanInfo beaninfo = Introspector.getBeanInfo(pt1.getClass());
PropertyDescriptor[] pds = beaninfo.getPropertyDescriptors();
Object retVal = null;
for(PropertyDescriptor pd : pds){
if(pd.getName().equals(propertyName)){
Method methodGetX = pd.getReadMethod();
retVal = methodGetX.invoke(pt1);
break;
}
}
return retVal;
}
}
5.加载器
用eclipse的打包工具将ClassLoaderTest输出成jre/lib/ext目录下的itcast.jar包,再在eclipse中运行这个类,运行结果显示为ExtClassLoader.此时的环境状态是classpath目录有ClassLoaderTest.class,ext/itcast.jar包中也有ClassLoaderTest.class,这时候我们就需要了解加载的具体过程和原理了。
类加载器的委托机制
当Java虚拟机要加载一个类时,到底派出那个类加载器去加载呢?
首先当前线程的类加载器去加载线程中的第一个类。
如果类A中引用了类B,java虚拟机将使用加载类的A的类加载器来加载类B.
还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类。
每个类加载器加载时,又先委托给其上级类加载器。
当所有祖宗类加载器没有加载到类,回到发起者类加载器,还加载不了,则抛ClassNotFountdException,不是再去找发起者类加载器的儿子,因为没有getChild方法,即使有,那么多儿子,找哪一个呢?
对着类加载器的参差结构图和委托加载原理,解释先前将ClassLoaderTest输出成jre/lib/ext目录下的itcast.jar包中后,运行结果为ExtClassLoader的原因。
编写自己的类加载器
自定义的类加载器的必须继承ClassLoader
loadClass方法与findClass方法
defineClass方法
编程步骤:
编写一个对文件内容进行简单加密的程序。
编写了一个自己的类装载器,可实现对加密过的类进行装载和解密。
编写一个程序调用类加载器加载类,在源程序中不能用该类名定义引用变量,因为编译器无法识别这个类。程序中可以除了使用ClassLoader.load方法之外,还可以使用设置线程的上下文类加载器或者系统类加载器,然后再使用Class.forName。
实验步骤:
对不带包名的class文件进行加密,加密结果存放到另外一个目录,例如: java MyClassLoader MyTest.class F:\itcast
运行加载类的程序,结果能够被正常加载,但打印出来的类装载器名称为AppClassLoader:java MyClassLoader MyTest F:\itcast
用加密后的类文件替换CLASSPATH环境下的类文件,再执行上一步操作就出问题了,错误说明是AppClassLoader类装载器装载失败。
删除CLASSPATH环境下的类文件,再执行上一步操作就没问题了。
代理的概念与作用
程序中的代理
要为已存在的多个具有相同接口的目标类的各个方法增加一些系统功能,例如,异常处理、日志、计算方法的运行时间、事务管理、等等,你准备如何做?
编写一个与目标类具有相同接口的代理类,代理类的每个方法调用目标类的相同方法,并在调用方法时加上系统功能的代码。 (参看下页的原理图)
如果采用工厂模式和配置文件的方式进行管理,则不需要修改客户端程序,在配置文件中配置是使用目标类、还是代理类,这样以后很容易切换,譬如,想要日志功能时就配置代理类,否则配置目标类,这样,增加系统功能很容易,以后运行一段时间后,又想去掉系统功能也很容易。
动态代理技术
要为系统中的各种接口的类增加代理功能,那将需要太多的代理类,全部采用静态代理方式,将是一件非常麻烦的事情!写成百上千个代理类,是不是太累!
JVM可以在运行期动态生成出类的字节码,这种动态生成的类往往被用作代理类,即动态代理类。
JVM生成的动态类必须实现一个或多个接口,所以,JVM生成的动态类只能用作具有相同接口的目标类的代理。
CGLIB库可以动态生成一个类的子类,一个类的子类也可以用作该类的代理,所以,如果要为一个没有实现接口的类生成动态代理类,那么可以使用CGLIB库。
代理类的各个方法中通常除了要调用目标的相应方法和对外返回目标返回的结果外,还可以在代理方法中的如下四个位置加上系统功能代码:
1.在调用目标方法之前
2.在调用目标方法之后
3.在调用目标方法前后
4.在处理目标方法异常的catch块中
[2] 开关机动画片及图片修改
来源: 互联网 发布时间: 2014-02-18
开关机动画及图片修改
开机动画开关
system/core/rootdir/etc/init.goldfish.sh
setprop debug.sf.nobootanimation 0
mediatek\custom\taibo13_gb\system\bootanim\bootanimation
mediatek\custom\taibo13_gb\system\bootanim\shutanimation
第一二张图片位置
\mediatek\custom\common\uboot\logo\wvga\wvga_kernel.bmp
\mediatek\custom\common\uboot\logo\wvga\wvga_uboot.bmp
MTK用bmp_to_raw转换成boot_logo文件,脚本在update文件,此文件在文件系统中media-images-boot_logo文件
第三张图片位置(如果没有开关机动画 开关机就会调用此处图片)
/frameworks/base/core/res/asserts/images/android-logo-mask.png
/frameworks/base/core/res/asserts/images/android-logo-shine.png
frameworks/base/core/java/com/android/internal/app/ShutdownThread.java
/frameworks/base/cmds/bootanimation/BootAnimation.cpp
/frameworks/base/cmds/bootanimation/BootAnimation.h
/frameworks/base/cmds/bootanimation/bootanimation_main.cpp
关机时去掉弹出框:
在ShutdownThread.java文件里找到beginShutdownSequence函数把mShutOffAnimation置为ture
然后把shutdownanimation.zip加到系统目录中,其制作可以参照下面文档
去掉关机充电进度条显示
快速开机 off:
/mediatek/platform/mt6573/uboot/mt6573_logo.c
快速开机 on:
/mediatek/source/external/ipod/bootlogo.c
去掉mt65xx_disp_draw_prog_bar函数
关于shutdownanimation.zip的制作:
开始写desc.txt 这个文件里面的命令。
desc.txt里面的命令格式如下:
480 800 30
p 1 0 part0
p 0 0 part1
480 800意思是说你开机动画在屏幕先以多少的分辨率显示,注意不要超过480x854的分辨率,
否则你的画面就显示不全了。
30 这个数字是代表着每秒播放的帧数,打个比方,part0文件夹里面共76个图片,
播放时间就是76/30=2.533333秒播放完毕,当然在手机里面会有一定的延时,尤其是你的图片文件
比较大的情况下,手机想播快也快不起来,卡啊
p 1(代表着播放一次) 0(空指令)part0 */这句指令就代表这part0文件夹内的图片只按名称顺序播放一次
p 0(重复播放)0 (空指令)part1 */这一句指令代表着part1文件夹内的图片会循环反复播放
还有一种是指令
p 0 10 part1 这里面的那个10代表着播放完part1文件夹内的图片一遍之后稍作停顿,然后再循环播放一遍,
再停顿少许,再播放,再停顿稍许·········重复下去
p 1 10 part1 同理,这句代表着播放完part1文件夹内的图片之后稍作停顿然后继续执行下一条命令。
图片准备好了,desc.txt里面的命令准备好了,就可以把他们一起打包压缩成zip格式了。
记住,是zip格式,而不是rar格式。另外压缩的时候注意一点,压缩的时候压缩方式要选择存储,否则开机时
手机会不认的。开机的时候会黑着没动画一直到进入桌面为止。
如果压缩完太大,重新解压用JPEG Imager软件处理再压缩zip格式。建议不要大于6M。
压缩文件重命名为bootanimation.zip之后,放在sd卡里面,按照之前的路径替换、重启
开机动画开关
system/core/rootdir/etc/init.goldfish.sh
setprop debug.sf.nobootanimation 0
mediatek\custom\taibo13_gb\system\bootanim\bootanimation
mediatek\custom\taibo13_gb\system\bootanim\shutanimation
第一二张图片位置
\mediatek\custom\common\uboot\logo\wvga\wvga_kernel.bmp
\mediatek\custom\common\uboot\logo\wvga\wvga_uboot.bmp
MTK用bmp_to_raw转换成boot_logo文件,脚本在update文件,此文件在文件系统中media-images-boot_logo文件
第三张图片位置(如果没有开关机动画 开关机就会调用此处图片)
/frameworks/base/core/res/asserts/images/android-logo-mask.png
/frameworks/base/core/res/asserts/images/android-logo-shine.png
frameworks/base/core/java/com/android/internal/app/ShutdownThread.java
/frameworks/base/cmds/bootanimation/BootAnimation.cpp
/frameworks/base/cmds/bootanimation/BootAnimation.h
/frameworks/base/cmds/bootanimation/bootanimation_main.cpp
关机时去掉弹出框:
在ShutdownThread.java文件里找到beginShutdownSequence函数把mShutOffAnimation置为ture
然后把shutdownanimation.zip加到系统目录中,其制作可以参照下面文档
去掉关机充电进度条显示
快速开机 off:
/mediatek/platform/mt6573/uboot/mt6573_logo.c
快速开机 on:
/mediatek/source/external/ipod/bootlogo.c
去掉mt65xx_disp_draw_prog_bar函数
关于shutdownanimation.zip的制作:
开始写desc.txt 这个文件里面的命令。
desc.txt里面的命令格式如下:
480 800 30
p 1 0 part0
p 0 0 part1
480 800意思是说你开机动画在屏幕先以多少的分辨率显示,注意不要超过480x854的分辨率,
否则你的画面就显示不全了。
30 这个数字是代表着每秒播放的帧数,打个比方,part0文件夹里面共76个图片,
播放时间就是76/30=2.533333秒播放完毕,当然在手机里面会有一定的延时,尤其是你的图片文件
比较大的情况下,手机想播快也快不起来,卡啊
p 1(代表着播放一次) 0(空指令)part0 */这句指令就代表这part0文件夹内的图片只按名称顺序播放一次
p 0(重复播放)0 (空指令)part1 */这一句指令代表着part1文件夹内的图片会循环反复播放
还有一种是指令
p 0 10 part1 这里面的那个10代表着播放完part1文件夹内的图片一遍之后稍作停顿,然后再循环播放一遍,
再停顿少许,再播放,再停顿稍许·········重复下去
p 1 10 part1 同理,这句代表着播放完part1文件夹内的图片之后稍作停顿然后继续执行下一条命令。
图片准备好了,desc.txt里面的命令准备好了,就可以把他们一起打包压缩成zip格式了。
记住,是zip格式,而不是rar格式。另外压缩的时候注意一点,压缩的时候压缩方式要选择存储,否则开机时
手机会不认的。开机的时候会黑着没动画一直到进入桌面为止。
如果压缩完太大,重新解压用JPEG Imager软件处理再压缩zip格式。建议不要大于6M。
压缩文件重命名为bootanimation.zip之后,放在sd卡里面,按照之前的路径替换、重启
[3] Java温习篇九
来源: 互联网 发布时间: 2014-02-18
Java复习篇九
从天津转站北京,爬到中关村到直立行走
Java复习篇九
Web应用
web页面
Html:超文本标记语言。
Html语言中是由标签组成的。
Html中的数据都会封装在标签中,因为可以通过标签中的属性值的改变对封装内数据进行操作。
确定html代码范围。<html></html>
在该范围中可以定义两部分内容,一部分是头,一部分是体。
<html>
<head></head>
<body></body>
</html>
Head:网页的一些属性信息。比如:标题。
Body:网页显示的数据。
标签特点:对于数据进行封装,那么就有开始标签和结束标签。但是也有一些标签只体 现单一功能,所以不需要结束标签,规范中要求标签必须结束,所以这样的标 签在内部结束。
如:<br/> <hr/><img/><input/>
标签格式:<标签名 属性名=“属性值”>数据</标签名>
<标签名 属性名=“属性值” />
常用标签:
1.字体:<font>
<font size="7" color="#ffff00">数据</font>
特殊部分:如果要在页面显示一些特殊符号,需要进行转义。
<: < >: > &; & 空格;
列表标签:<dl></dl>
上层项目:<dt>
下层项目:<dd>
项目符号标签:
<ul>
<ol>
这两个标签中的列表项都由<li>标签封装。
示例:
游戏名称
星际
红警
游戏内容
攻略
秘籍
3.图像标签:<img>
<img src ="" alt="图像说明文字">
表格标签:<table>
表格由行所组成,行由单元格组成。
表格中默认都有一个tobody标签。
<table>
<tr>
<th><th>
<th><th>
</tr>
<tr>
<td><td>
<td><td>
</tr>
</table>
5.
表单标签
该标签可以和服务端进行交互的。
<form>
表单标签中元素:
<input>:该标签因为type属性的值的不同,所对应的组件也不一样。
Type属性:
text:文本框,输入的文本可见。
Password:密码框,输入的文本不可见。
Radio:单选框,注意,要被选中,必须要给单选框定义一个属性name.当有多个单选框时,只能有一个别选中,那么这些单选框的name值必须相同。
Checkbox:复选框,当对多个数据进行同时选中时。
File:可以进行文件选件的组件。通常用于福建,或者文件上传。
Hidden:隐藏组件,该组件的不会页面上显示,但是其定义的name和Value可以提交到服务端。
Button:按钮组件,自定义一个按钮默认是没有任何效果的,可以通过注册事件并加入到自定义效果。
Reset:重置按钮,将组件中添加的数据提交到指定的目的地。
Submit:提交按钮,将组件中添加的数据提交到指定的目的地。
Image:图像组件,为了避免提交按钮的难看,可以通过image的src属性连接一个好看的按钮图片完成提交效果。
下拉菜单:<select>
每一个下拉菜单项有option进行封装。
<select>
<option></option>
</select>
文本区域:<textare>
表单组件通常都需要定义name和value属性,因为要将数据发送给服务端。
服务端只有知道了该name的值才可以对提交的数据进行分别获取。
Form标签中的常见属性:
Action:指定数据提交的目的地,method:提交方式。两种常用值get和post,get为默认。
Get和post的区别:
Get,会将提交的数据显示在地址栏上。提交的数据的体积受地址栏的限制;对于敏感信息不安全;会将提交信息封装在请求行,也就是http消息头之前。
Post:不会将数据显示在地址栏;可以提交大体积数据;对于敏感信息安全;会将提交信息封装在数据体中,也就是http消息头之后的空行后。
对于服务端而言:
表单提交尽量用post,因为涉及到编码问题。
对于post提交的中文,在服务端可以直接使用setCharacterEncoding("gbk")就可以解决。
对于get提交的中文,在服务端只能通过ISO58859-1将数据编码一次,在通过制定的码表如GBK解码。
使用表单的组件不一定要定义form标签。只有需要将数据进行服务端的提交的时候才会用到form标签。
2正则表达式:是一种专门用于操作字符串的规则。
通过一些符号来表示,简化对字符串的复杂操作。
弊端:阅读性差。
常用操作:
匹配:String.matches()
获取(查找):Pattern,Matcher
Pattern p = Pattern.compile(regex);
Mather m = p.matcher(String);
While(m.find()){
System.out.println()m.group();
}
切割:String split(regex);
替换:String replaceAll(regex,str)
示例:
String regex = "\\d{5,}";
Pattern p = Pattern.copile(regex);
Matcher m = p.matcher(String);
While(m.find()){
String s = m.group();
s.replaceAll(regex,"#");
}
网页爬虫:
通过网络以及IO流读取网页的源文件,并通过规则获取网页中的符合规则的数据。
比如:mail爬虫
String mailereg = "[a-zA-Z0-9][6,12]@[a-zA-Z0-9]+{\\.[a-zA-Z]+}+";
正则表达式中组的含义,将部分惊醒封装以便重用。\\num 反向应用指定组
从天津转站北京,爬到中关村到直立行走
Java复习篇九
Web应用
web页面
Html:超文本标记语言。
Html语言中是由标签组成的。
Html中的数据都会封装在标签中,因为可以通过标签中的属性值的改变对封装内数据进行操作。
确定html代码范围。<html></html>
在该范围中可以定义两部分内容,一部分是头,一部分是体。
<html>
<head></head>
<body></body>
</html>
Head:网页的一些属性信息。比如:标题。
Body:网页显示的数据。
标签特点:对于数据进行封装,那么就有开始标签和结束标签。但是也有一些标签只体 现单一功能,所以不需要结束标签,规范中要求标签必须结束,所以这样的标 签在内部结束。
如:<br/> <hr/><img/><input/>
标签格式:<标签名 属性名=“属性值”>数据</标签名>
<标签名 属性名=“属性值” />
常用标签:
1.字体:<font>
<font size="7" color="#ffff00">数据</font>
特殊部分:如果要在页面显示一些特殊符号,需要进行转义。
<: < >: > &; & 空格;
列表标签:<dl></dl>
上层项目:<dt>
下层项目:<dd>
项目符号标签:
<ul>
<ol>
这两个标签中的列表项都由<li>标签封装。
示例:
游戏名称
星际
红警
游戏内容
攻略
秘籍
3.图像标签:<img>
<img src ="" alt="图像说明文字">
表格标签:<table>
表格由行所组成,行由单元格组成。
表格中默认都有一个tobody标签。
<table>
<tr>
<th><th>
<th><th>
</tr>
<tr>
<td><td>
<td><td>
</tr>
</table>
5.
表单标签
该标签可以和服务端进行交互的。
<form>
表单标签中元素:
<input>:该标签因为type属性的值的不同,所对应的组件也不一样。
Type属性:
text:文本框,输入的文本可见。
Password:密码框,输入的文本不可见。
Radio:单选框,注意,要被选中,必须要给单选框定义一个属性name.当有多个单选框时,只能有一个别选中,那么这些单选框的name值必须相同。
Checkbox:复选框,当对多个数据进行同时选中时。
File:可以进行文件选件的组件。通常用于福建,或者文件上传。
Hidden:隐藏组件,该组件的不会页面上显示,但是其定义的name和Value可以提交到服务端。
Button:按钮组件,自定义一个按钮默认是没有任何效果的,可以通过注册事件并加入到自定义效果。
Reset:重置按钮,将组件中添加的数据提交到指定的目的地。
Submit:提交按钮,将组件中添加的数据提交到指定的目的地。
Image:图像组件,为了避免提交按钮的难看,可以通过image的src属性连接一个好看的按钮图片完成提交效果。
下拉菜单:<select>
每一个下拉菜单项有option进行封装。
<select>
<option></option>
</select>
文本区域:<textare>
表单组件通常都需要定义name和value属性,因为要将数据发送给服务端。
服务端只有知道了该name的值才可以对提交的数据进行分别获取。
Form标签中的常见属性:
Action:指定数据提交的目的地,method:提交方式。两种常用值get和post,get为默认。
Get和post的区别:
Get,会将提交的数据显示在地址栏上。提交的数据的体积受地址栏的限制;对于敏感信息不安全;会将提交信息封装在请求行,也就是http消息头之前。
Post:不会将数据显示在地址栏;可以提交大体积数据;对于敏感信息安全;会将提交信息封装在数据体中,也就是http消息头之后的空行后。
对于服务端而言:
表单提交尽量用post,因为涉及到编码问题。
对于post提交的中文,在服务端可以直接使用setCharacterEncoding("gbk")就可以解决。
对于get提交的中文,在服务端只能通过ISO58859-1将数据编码一次,在通过制定的码表如GBK解码。
使用表单的组件不一定要定义form标签。只有需要将数据进行服务端的提交的时候才会用到form标签。
2正则表达式:是一种专门用于操作字符串的规则。
通过一些符号来表示,简化对字符串的复杂操作。
弊端:阅读性差。
常用操作:
匹配:String.matches()
获取(查找):Pattern,Matcher
Pattern p = Pattern.compile(regex);
Mather m = p.matcher(String);
While(m.find()){
System.out.println()m.group();
}
切割:String split(regex);
替换:String replaceAll(regex,str)
示例:
String regex = "\\d{5,}";
Pattern p = Pattern.copile(regex);
Matcher m = p.matcher(String);
While(m.find()){
String s = m.group();
s.replaceAll(regex,"#");
}
网页爬虫:
通过网络以及IO流读取网页的源文件,并通过规则获取网页中的符合规则的数据。
比如:mail爬虫
String mailereg = "[a-zA-Z0-9][6,12]@[a-zA-Z0-9]+{\\.[a-zA-Z]+}+";
正则表达式中组的含义,将部分惊醒封装以便重用。\\num 反向应用指定组
最新技术文章: