第一篇:黑马程序员:工具类----获取指定包名下的所有类[本站推荐]
分享一个获取指定包名下所有类的工具类,代码如下
1.2.3.4.5.6.7.8.9.import java.io.File;import java.io.FileFilter;
import java.lang.annotation.Annotation;import java.net.JarURLConnection;import java.net.URL;
import java.util.ArrayList;import java.util.Enumeration;import java.util.List;
import java.util.jar.JarEntry;
10.import java.util.jar.JarFile;11.12.public class ClassUtil { 13.// 获取指定包名下的所有类 14.public static List
15.List
urls
= Thread.currentThread().getContextClassLoader().getResources(packageName.replaceAll(“.”, “/”));
18.while(urls.hasMoreElements()){ 19.URL url = urls.nextElement();20.if(url!= null){
21.String protocol = url.getProtocol();22.if(protocol.equals(“file”)){
23.String packagePath = url.getPath();
24.addClass(classList, packagePath, packageName, isRecursive);
25.} else if(protocol.equals(“jar”)){ 26.27.28.JarURLConnection jarURLConnection =(JarURLConnection)url.openConnection();
JarFile
jarFile
= jarURLConnection.getJarFile();
Enumeration
29.while(jarEntries.hasMoreElements()){
30.JarEntry jarEntry = jarEntries.nextElement();
31.String jarEntryName = jarEntry.getName();32.if(jarEntryName.endsWith(“.class”)){ 33.String
className
= jarEntryName.substring(0, jarEntryName.lastIndexOf(“.”)).replaceAll(“/”, “.”);
34.{
if(isRecursive || className.substring(0, className.lastIndexOf(“.”)).equals(packageName))35.classList.add(Class.forName(className));
36.} 37.} 38.} 39.} 40.} 41.}
42.} catch(Exception e){ 43.e.printStackTrace();44.}
45.return classList;46.} 47.48.// 获取指定包名下的所有类(可根据注解进行过滤)49.public static List
50.List
urls
= Thread.currentThread().getContextClassLoader().getResources(packageName.replaceAll(“.”, “/”));
53.while(urls.hasMoreElements()){ 54.URL url = urls.nextElement();55.if(url!= null){
56.String protocol = url.getProtocol();57.if(protocol.equals(“file”)){
58.String packagePath = url.getPath();
59.addClassByAnnotation(classList, packagePath, packageName, annotationClass);
60.} else if(protocol.equals(“jar”)){ 61.62.63.JarURLConnection jarURLConnection =(JarURLConnection)url.openConnection();
JarFile
jarFile
= jarURLConnection.getJarFile();
Enumeration
64.while(jarEntries.hasMoreElements()){ 65.JarEntry
jarEntry
= jarEntries.nextElement();
66.String jarEntryName = jarEntry.getName();67.if(jarEntryName.endsWith(“.class”)){ 68.String
className
= jarEntryName.substring(0, jarEntryName.lastIndexOf(“.”)).replaceAll(“/”, “.”);
69.70.Class> cls = Class.forName(className);
if(cls.isAnnotationPresent(annotationClass)){
71.classList.add(cls);72.} 73.} 74.} 75.} 76.} 77.}
78.} catch(Exception e){ 79.e.printStackTrace();80.}
81.return classList;82.} 83.84.private static void addClass(List
85.try {
86.File[] files = getClassFiles(packagePath);
87.if(files!= null){
88.for(File file : files){
89.String fileName = file.getName();90.if(file.isFile()){
91.String className = getClassName(packageName, fileName);
92.classList.add(Class.forName(className));93.} else {
94.if(isRecursive){ 95.96.97.String subPackagePath = getSubPackagePath(packagePath, fileName);
String subPackageName = getSubPackageName(packageName, fileName);
addClass(classList, subPackagePath, subPackageName, isRecursive);
98.} 99.} 100.} 101.}
102.} catch(Exception e){ 103.e.printStackTrace();104.} 105.} 106.107.private static File[] getClassFiles(String packagePath){ 108.return new File(packagePath).listFiles(new FileFilter(){ 109.@Override
110.public boolean accept(File file){ 111.return
(file.isFile()
&& file.getName().endsWith(“.class”))|| file.isDirectory();
112.} 113.});114.} 115.116.private static String getClassName(String packageName, String fileName){
117.String className = fileName.substring(0, fileName.lastIndexOf(“.”));
118.if(org.apache.commons.lang.StringUtil.isNotEmpty(packageName)){
119.className = packageName + “.” + className;120.}
121.return className;122.} 123.124.private static String getSubPackagePath(String packagePath, String filePath){
125.String subPackagePath = filePath;126.if(org.apache.commons.lang.StringUtil.isNotEmpty(packagePath)){
127.subPackagePath = packagePath + “/” + subPackagePath;128.}
129.return subPackagePath;130.} 131.132.private static String getSubPackageName(String packageName, String filePath){
133.String subPackageName = filePath;134.if(org.apache.commons.lang.StringUtil.isNotEmpty(packageName)){
135.subPackageName = packageName + “.” + subPackageName;136.}
137.return subPackageName;138.} 139.140.private static void addClassByAnnotation(List
141.try {
142.File[] files = getClassFiles(packagePath);143.if(files!= null){
144.for(File file : files){
145.String fileName = file.getName();146.if(file.isFile()){
147.String className = getClassName(packageName, fileName);
148.Class> cls = Class.forName(className);149.if(cls.isAnnotationPresent(annotationClass)){
150.classList.add(cls);151.} 152.} else { 153.154.155.String
subPackagePath
= getSubPackagePath(packagePath, fileName);
String
subPackageName
= getSubPackageName(packageName, fileName);
addClassByAnnotation(classList, subPackagePath, subPackageName, annotationClass);
156.} 157.} 158.}
159.} catch(Exception e){ 160.e.printStackTrace();161.} 162.} 163.}
第二篇:黑马程序员_PHP_课程同步笔记day30:PHP类中关键字
【黑马程序员济南】PHP课程同步笔记day30:PHP类中
关键字
今天我来为大家讲解一下PHP类中的一些关键字: parent和self关键字 parent:
用在一个类的一个方法中;
代表这个类的“父类”——注意,是代表一个类,不是类的对象;
但:实际应用中,常常会看起来“代表”这个类的父类对象——因为用的时候,是使用了父类的对象来调用某个方法而产生了所谓的对象传递; [PHP] 纯文本查看 复制代码 ? 01
黑马程序员济南中心 编著 1;//声明静态属12 性 13 } 14 15 class B extends A{ static function f1(){ echo “父类的静态属性s1:”.parent::$s1;echo “父类的常量PI:”.parent::PI;} } B::f1();显示结果:
父类的静态属性s1:1
父类的常量PI:3.14
黑马程序员济南中心 编著
self:
用在一个类的一个方法中;
代表这个类“本身”——还是代表一个类,而不是类的对象; [PHP] 纯文本查看 复制代码 ? 01
黑马程序员济南中心 编著
己的常量PI:”.self::PI;} } B::f1();典型使用1:
在构造方法中,调用父类的构造方法,以完成对象的一些共同的数据初始化工作。[PHP] 纯文本查看 复制代码 ? 01
04 class Member{ 05 public $name;//声明一个变量 06 public $salary;//声明一个变量 07 //创建一个构造方法 08 function
09 __construct($name,$salary){ 10 $this->name = $name;//把实例11 化类时的实参传递给之前声明好的变量 12 $this->salary = $salary;//把实例13 化类时的实参传递给之前声明好的变量
黑马程序员济南中心 编著 } 15 } 16 class Teacher extends Member{ 17 public $edu;//声明一个变量 18 //创建一个构造方法 19 function __construct($name,$salary,$edu){ 21 //$this->name = $name;22 //$this->salary = $salary;23 //将上面两行的内容用下面一行类24 代替 //调用父类的构造方法,去完成一个26 共同属性数据的初始化 parent::__construct($name,$salar28 y);29 //把实例化类时的实参传递给之前声30 明好的变量
$this->edu = $edu;32 } 33 } 34 class Student extends Member{ 35 public $age;//声明一个变量
黑马程序员济南中心 编著
//创建一个构造方法 37 function
__construct($name,$salary,$age){ 39
//调用父类的构造方法,去完成一个41 共同属性数据的初始化
parent::__construct($name,$salary);//把实例化类时的实参传递给之前声明好的变量
$this->age = $age;} } $t1 = new Teacher(“老师”,1000,“大学”);echo “
”;var_dump($t1);echo “
”;$s1 = new Student(“学生”,100,18);var_dump($s1);
黑马程序员济南中心 编著
不知道大家对今天讲解的parent和self关键字学习的程度如何啊?如果有兴趣,欢迎来黑马程序员济南中心来详细了解PHP~
黑马程序员济南中心 编著
第三篇:黑马程序员_PHP_课程同步笔记day33:类和对象的其他相关技术[推荐]
类和对象的其他相关技术
类的自动加载: 基本概念:
当在一个代码中,需要使用一个类(比如new),但此时,在这行代码之前,都没有出现过该类的定义,则php有一种机制,可以让系统这个时候去调用一个函数,在该函数中,我们就可以预先写好加载类的代码——这样就实现了类的自动加载。
该函数就是:__autoload()该函数使用形式如下:
function __autoload($class_name){
//这里就可以去写加载类的代码,其中:
//$class_name就代表“正需要”的那个类名;
} [PHP] 纯文本查看 复制代码 ? 1
黑马程序员济南中心 编著
可见,实现这种类的自动加载的方便性,需要做到:
1,类文件名有一个统一的形式:比如:类名.clsss.php
2,统一都放在一个文件夹中;
3,尽可能做到:一个类文件中,只放一个类的定义;
自定义类的加载函数
使用下述函数,可以人为定义“多个”自动加载函数(这些函数的作用跟__autoload)一样。使用形式:
spl_autoload_register(“自动加载函数名1”);
spl_autoload_register(“自动加载函数名2”);
。。
然后就可以去定义这些函数了
在运行的时候,如果需要一个类,就先调用第1个函数去“试图”加载该类,如果在该函数中没有加载成功,就会继续调用下一个函数继续“试图”加载该类,依此类推。。举例:
[PHP] 纯文本查看 复制代码 ? 01
04 spl_autoload_register(“auto1”);
黑马程序员济南中心 编著
05 spl_autoload_register(“auto2”);06 function auto1($class_name){ 07 echo “
进入auto1,需要:$class_name”;08 $file = “./{$class_name}.class.php”;09 if(file_exists($file)){ 10 include_one $file;11 } 12 } 13 function auto2($class_name){ 14 echo “
进入auto2,需要:$class_name”;15 $file = “./{$class_name}.class.php”;16 if(file_exists($file)){ 17 include_one $file;18 } 19 } 20 $obj1 = new A();22 echo “
”;23 var_dump($obj1);24 $obj2 = new B();26 echo “
”;
黑马程序员济南中心 编著 var_dump($obj2);
展示结果为: 进入auto1,需要:A object(A)#1(0){} 进入auto1,需要:B 进入auto2,需要:B object(B)#2(0){}
对象的复制
$obj1 = new A();
$obj2 = $obj1;
//这里,虽然是值传递,但因为对象数据存储的特殊性,并没有复制对象数据本身
//即,并没有生成一个新对象;
要想复制一个对象——得到一个完完全全的相同的对象,只能这样:
$obj3 = clone $obj1;[PHP] 纯文本查看 复制代码 ? 01
黑马程序员济南中心 编著
05 } 06
07 $obj1 = new A();08 $obj2 = $obj1;09 $obj3 = clone $obj1;10 var_dump($obj1);11 var_dump($obj2);12 var_dump($obj3);13 $obj1->p1 = 11;15 var_dump($obj1);16 var_dump($obj2);17 var_dump($obj3);展示效果:
object(A)#1(1){[“p1”]=>int(1)} object(A)#1(1){[“p1”]=>int(1)} object(A)#2(1){[“p1”]=>int(1)}
object(A)#1(1){[“p1”]=>int(11)} object(A)#1(1){[“p1”]=>int(11)} object(A)#2(1){[“p1”]=>int(1)}
黑马程序员济南中心 编著
可见,普通赋值所得到的对象,仍然是原来的对象;
只有clone所得到的对象,才是一个全新的对象; 注意:
1,当对一个对象进行克隆的时候,就会自动调用系统中的__clone()魔术方法(如果有);
2,因此,对于单例类的需求来说,就应该做到:禁止克隆,写法:
private function __clone(){ }
对象的遍历
跟数组类似,对象的“所有属性”,也是可以进行遍历的——一个一个取出。
形式:
foreach($对象 as $prop => $value){
//$prop表示属性名;
//$value表示对应的属性值;
} 注意:
其实能取到的属性数据,只是在该位置可以访问(有权限访问)到的那些。[PHP] 纯文本查看 复制代码 ? 01
黑马程序员济南中心 编著
04 05 class A{ 06 public $p1 = 1;07 protected $p2 08 = 2;09 private $p3 = 3;10 static $p4 = 4;11 function 12 showInfo(){ 13 foreach($this 14 as $prop=>$value){ 16 echo “属性17 $prop = $value”;18 } 19 } 20 } 21
$a1 = new A();foreach($a1 as $prop=>$value){ echo “属性
黑马程序员济南中心 编著
$prop = $value”;}
$a1->showInfo();展示效果: 属性p1 = 1;
属性p1 = 1 属性p2 =2 属性p3 = 3
不知道大家对今天讲的类和对象的其他相关技术学习的怎么样啊?有什么疑问欢迎来黑马程序员济南中心来咨询哟~
黑马程序员济南中心 编著
第四篇:黑马程序员_PHP_课程同步笔记day34:PHP类其他魔术方法
【黑马程序员济南】PHP类其他魔术方法
序列化:
就是将一个变量的“内存数据形式”,转换为“硬盘数据形式”的过程。
分2步就可以:
1,$str = serialize($变量);//该函数将该变量数据,转换为一个字符串
2,file_put_contents(“文本文件名”, $str);//将该字符串保存到该文件中。[PHP] 纯文本查看 复制代码 ? 01 5.5,'bbcc'=>true);13 $data3 = new A();
黑马程序员济南中心 编著 //开始转换得到一个字符串 16 $str1 = serialize($data1);17 $str2 = serialize($data2);18 $str3 = serialize($data3);19 //开始写入硬盘中 file_put_contents('./file1.txt',$str1);22 file_put_contents('./file2.txt',$str2);23 file_put_contents('./file3.txt',$str3);24
[align=left] 反序列化:
将已经存到硬盘的变量数据,转换(恢复)到内存数据(变量)形式的过程。同样分2步:
1,$str = file_get_contents(文本文件名);
//读取出序列化之后所存储的文件内容(就是字符串)
2,$变量 = unserialize($str);
//将该字符串恢复为变量(数据);
[PHP] 纯文本查看 复制代码 ? 01
黑马程序员济南中心 编著
02 //演示3中数据的序列化结果 03 class A{ 04 public $p1 = 1;05 protected $p2 = 2;06 private $p3 = 3;07 } 08
09 //开始从硬盘中读取数据(字符串)10 $str1 = file_get_contents('./file1.txt');11 $str2 = file_get_contents('./file2.txt');12 $str3 = file_get_contents('./file3.txt');13 //开始转换得到一个字符串 15 $data1 = unserialize($str1);16 $data2 = unserialize($str2);17 $data3 = unserialize($str3);18 var_dump($data1);20 var_dump($data2);21 var_dump($data3);结果为: float(1.1)
黑马程序员济南中心 编著
array(3){[0]=>string(2)“aa” [5]=>float(5.5)[“bbcc”]=>bool(true)} object(A)#1(3){[“p1”]=>int(1)[“p2”:protected]=>int(2)[“p3”:“A”:private]=>int(3)} __sleep():
该魔术方法是对一个对象进行“序列化”的时候,会被自动调用。
此时,在该方法中,我们就可以(而且必须)返回一个数组,该数组中含所有我们“想要”对该对象的属性进行序列化的属性名。[PHP] 纯文本查看 复制代码 ? 01
黑马程序员济南中心 编著 }
__wakeup()
该魔术方法是对一个对象进行“反序列化”的时候,会被自动调用。
此时,该对象的属性值,就会恢复到“原来的数据”
但:如果某个属性当时并没有做序列化,则此时就不会恢复为原来对象的数据,而是恢复为该类中的初始数据; [PHP] 纯文本查看 复制代码 ? 01
黑马程序员济南中心 编著 $this->p1 = $p1;13 $this->p2 = $p2;14 $this->p3 = $p3;15 } 16 function __sleep(){ 17 return 18 array(“p1”,“p3”);19 } 20 function 21 __wakeup(){ 22 echo “对象苏醒23 了。。”;24 } 25 } 26
$s1 = new S(11,12,13);$str = serialize($s1);var_dump($)
[align=left]
黑马程序员济南中心 编著
不知道大家对今天讲的PHP类其他魔术方法相关技术学习的怎么样啊?有什么疑问欢迎来黑马程序员济南中心来咨询哟~
黑马程序员济南中心 编著
第五篇:黑马程序员java培训就业班笔记:day14(多线程、String类)总结
Day14总结:
1、wait和sleep的区别:(面试题)
1、sleep指定时间,wait可以指定时间,也可以不用指定时间。
2、wait方法必须定义在同步中,sleep方法不一定。
3、在同步中wait sleep对于执行权和锁的处理不同: i.Sleep释放CPU执行权,但是没有释放锁。ii.Wait释放执行权、释放锁。实现代码: Public void run(){ Synchronized(this){ Code…sleep(10);//此线程进入冻结状态,释放了执行权,并没有释放锁。
Wait();//等待状态下,释放执行权、释放锁,因为它需要被对象唤醒,所以要释放锁
} } Public void method(){ Synchronized(this){
notifyAll();//唤醒上面所有的线程。但是此时t0、t1并没有执行,因为锁还在此线程中,只有当它执行完毕之后,释放锁。它们获取锁之后才有机会执行。
} }
2、停止线程:
1、Stop方法已经过时,为什么?因为该方法具有不固定的安全性。
如何停止线程? 只有一种方法:
线程执行的代码结束,线程会自动终止。
1、run方法中通常有循环,所以只要循环结束即可。所以只要控制循环条件。最简单的方式就是定义标记。
2、如果run中有同步可以让线程出现冻结状态的方法,比如wait那么线程就不会去读取标记。这时必须让线程恢复到运行状态才可以有机会读取到标记,所以通过正常的恢复方法比如notify、sleep时间到,但是如果没有办法正常恢复,就必须使用强制手段,interrupt方法,强制将线程的冻结状态清除,让线程恢复运行。其实就是让线程重新获取读取标记、结束。但是别忘了强制动作会产生异常要处理。实现代码:
StopThreadDemo.java
class StopThread implements Runnable
{ private boolean flag=true;//定义标记控制住循环。public synchronized void run(){ while(flag)//开始true、此时定义标记控制循环。
{
try
{
wait();//当存在同步时,wait方法不会让线程去读取标记。此时主线程结束了,但是这两个线程却在这里等待了。并没有结束。
}
catch(InterruptedException e)
{
System.out.println(Thread.currentThread().getName()+“....Exception”);
setFlag();//如果发生了强制中断,只要把状态切断到假。
}
System.out.println(Thread.currentThread().getName()+“...”);} } public void setFlag(){ flag=false;} }
class StopThreadDemo { public static void main(String[] args){ StopThread st=new StopThread();Thread t1=new Thread(st);Thread t2=new Thread(st);t1.start();t2.setDaemon(true);//标记成了守护线程。
t2.start();
for(int x=0;;x++){
if(x==50)
{
st.setFlag();
t1.interrupt();//t1将它的冻结状态强制结束。
t2.interrupt();//中断方法。其实不是中断线程。而且还抛出了异常。
//其实会将冻结中的线程强行恢复到运行状态,就会读到标记。这就是中断线程。并不是结束线程。一定要注意要区分。
//
break;
}
System.out.println(Thread.currentThread().getName()+“....”);}
System.out.println(“Hello World!”);} }
3、守护线程:setDaemon();线程标记,守护线程,当正在运行的线程是守护线程时,JVM自动退出,该方法在开启之前调用,也就是说在start方法之前调用。
线程分两种:
前台线程:自己创建的线程都是前台线程。
后台线程:一旦调用了此方法为守护线程之后的线程都是守护线程。
区别:都是线程,启动后都再抢夺CPU的执行权,这里是没有区别的,最大的区别就是如果线程结束了,正在运行的后台线程也随着结束,简单的说后台线程是以来前台线程而执行的。
4、线程细节:
1、join:当A线程执行到B线程时,那么A线程就会等待,等B执行完毕,A才会执行。
代码实现:
D1.join();d1加入,说明了主线程必须先释放执行权给它,等到d1结束之后主线程才恢复执行状态,所以输出结果是等d1全部都执行完毕之后,才有其他线程的交替执行。
记住:谁把执行权给了谁,就只和给的对象的执行权有关,等它结束之后,就会重新获取执行
记住:主线程是因为谁放弃了执行权,就只和那个线程有关系权,与其他线程无关。
2、优先级:代表抢夺资源的频率。有两种方法:getPriority setPriority来获取优先级和设置优先级,只有十个数字可以使用1-10这十个数字,同时线程中提供了几个特殊的方法: 线程类中提供了MAX_PRIORITY MIN_PRIORTY NORM_PRIORTY。
3、yield:结束该线程,释放执行权。
4、toString();获取线程详细信息,包括线程组、线程名、所属线程。实现代码:ThreadMethodDemo.java
5、string类:
1、字符串的特点:
1、java中用String类来描述字符串。
2、字符串是一个特殊的对象,一旦初始化就不可以被改变,因为是常量。面试题1: String s=“abc”;String s1=new Strng(“abc”);是否相同?
前者“abc”是一个对象。后者是两个对象,new string()代表一个对象,“abc”也代表一个对象。
Sop(s1==s2);==比较的是数据。false Sop(s1.equals(s2));比较的是内存的地址值,equals覆写了Object类中的equals方法。True
面试题2: String a=“abcd”;//在缓冲池创建了一个abcd的字符串。String a1=“ab”;//a1和a2都是变量,无法确定。
String a2=“cd”;String b=a1+a2;//b是要重新进行分配的。
String c=“ab”+“cd”;//两个都是常量值,用连接符连接在一起还是字符创。abcd System.out.println(“a==b:”+(a==b));//false System.out.println(“a==c:”+(a==c));//true
2、常见操作方法:
1、获取:
a)获取长度:
Int length();数组长度是个属性,字符串是个方法 b)获取字符串中的字符:
charAt(int index);返回值是一个字符。
c)一个字符或者一个字符串在一个字符串中的位置
Int indexof(int ch)Int indexof(int ch,int fromIndex)Int indexof(ch,fromIndex)Int indexof(srting,fromindex)Int lastIndexof(ch);注意:这些获取索引位的方法,如果没有查找的内容,返回-1,所以这个方法。
d)获取部分字符串:
String substring(begin,end)
2、判断:
a)是否包含指定的字符串
Boolean contains(String)
b)是否是以指定的字符串开头
Boolean startsWith(String)c)是否是以指定的字符串结尾
Boolean endwith(String)d)忽略大小写判断字符串
Boolean equalsIgnoreCase(string)
3、转换:
a)将字符串转成大小写
String toLowerCase();String toUpperCase();b)将字符串转成数组
Byte[] getBytes();Char[] getChar();c)将字符串转成字符串数组
String[] d)将字符串中的内容进行替换
String replace(oldch1,new ch2)String replace(string1,string2)e)去除字符串两端的空白
Trim();如何查阅API文档的小技巧,先查找返回值类型,缩小查找范围。实现代码:
ublic static void main(String[] args){
// stringMethod4();
String str = “
ab c
”;
System.out.println(“-”+str.trim()+“-”);
String s = String.valueOf(4);
System.out.println(4+“");
System.out.println(”ab“+”cd“);
System.out.println(”ab“.concat(”cd“));
}
private static void stringMethod4(){
String str = ”lisi.wangwu.zhaoliu“;
} String[] strs = str.split(”.“);for(int i = 0;i < strs.length;i++){ System.out.println(strs[i]);}
str = ”hello“;
String s = str.replace('a', 'k');
System.out.println(”s=“+s);System.out.println(str);private static void stringMethod3(){
String str = ”aBCd“;
String s = str.toLowerCase();System.out.println(s);String s1 = str.toUpperCase();System.out.println(s1);
System.out.println(str);
char[] arr = str.toCharArray();
for(int x = 0;x System.out.println(arr[x]);} } private static void stringMethod2(){ String str = ”ThreadDemo.java“; System.out.println(”contains(Demo):“+str.contains(”Demo“));System.out.println(”starsWith(Thread):“+str.startsWith(”Thread“));System.out.println(”endsWith(.java):“+str.endsWith(”.java“));System.out.println(”isEmpty:“+str.isEmpty());str = ”abc“;说 System.out.println(str.equalsIgnoreCase(”abC“));} private static void stringMethod(){ String str = ”abcdaef“;System.out.println(”length;“+str.length()); System.out.println(”charAt(2):“+str.charAt(2)); System.out.println(”indexOf(a):“+str.indexOf('a',2)); System.out.println(”lastIndexOf(a):“+str.lastIndexOf('k')); System.out.println(”substring(1,3):"+str.substring(0,str.length()));}