Presentation is loading. Please wait.

Presentation is loading. Please wait.

Object Oriented Programming in Java Lecture 7 (Dynamic Java and reflection. Generics in depth. Regexps) Szymon Grabowski

Similar presentations


Presentation on theme: "Object Oriented Programming in Java Lecture 7 (Dynamic Java and reflection. Generics in depth. Regexps) Szymon Grabowski"— Presentation transcript:

1 Object Oriented Programming in Java Lecture 7 (Dynamic Java and reflection. Generics in depth. Regexps) Szymon Grabowski sgrabow@kis.p.lodz.pl http://szgrabowski.kis.p.lodz.pl/ zpo / Thx to Wojciech Bieniecki for sharing stuff and friendly advices Łódź, 2010

2 2 Reflection [ ftp://ftp.oreilly.com/pub/conference/java2001/Portwood_Reflection.ppt ] Java provides two ways to discover information about an object at runtime:  Traditional runtime class identification  The object’s class is available at compile and runtime  Reflection  The object’s class may not be available at compile or runtime. Reflection (...) refers to the ability to observe and/or manipulate the inner workings of the environment programmatically.

3 3 Every class loaded into the JVM has a Class object –Corresponds to a.class file –The ClassLoader is responsible for finding and loading the class into the JVM At object instantiation… –The JVM checks to see if the class is already loaded into the virtual machine –Locates and loads the class if necessary –Once loaded, the JVM uses the loaded class to instantiate an instance How the Class object works [ ftp://ftp.oreilly.com/pub/conference/java2001/Portwood_Reflection.ppt ]

4 4 Reflection – what can I do with it? [ ftp://ftp.oreilly.com/pub/conference/java2001/Portwood_Reflection.ppt ] –Load a class –Determine if it is a class or interface –Determine its superclass and implemented interfaces –Instantiate a new instance of a class –Determine class and instance methods –Invoke class and instance methods –Determine and possibly manipulate fields –Determine the modifiers for fields, methods, classes, and interfaces –...

5 5 A very simple class [ http://www.onjava.com/pub/a/onjava/2007/03/15/ reflections-on-java-reflection.html ]

6 6 Looking into Employee’s internals... Class name: Employee Class super class: class java.lang.Object Class is public: true Class is final: false Class is abstract: false Output

7 7 There are 3 ways to get hold of a class object 1.Calling getClass on an instance (we used it in the example). 2. Getting it directly from a class name: Class klass = Employee.class; 3. Creating a Class object from a string: Class klass = Class.forName("javax.swing.JButton");... System.out.println("Class name: " + klass.getName());... System.out.println("Class super class: " + klass.getSuperclass());

8 8 About forName: you need to supply the full, complete with the package, name of the class. Creating a Class object from a string

9 9 Do smth with a Class object! Make a new instance of the “hold” class: newInstance() method. public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException { Class klass = Class.forName(args[0]); Object theNewObject = klass.newInstance(); System.out.println("Just made: " + theNewObject); } Run with Employee argument (remember about the package name, if not the same); you will see: Just made: Employee: John Smith 50000

10 10 Delaying the way an action is handling until the run-time ([Barteczko'00]) 1/2

11 11 Delaying the way an action is handling until the run-time ([Barteczko'00]) 2/2

12 12 Reflection can simplify code. A factory design pattern example [ ftp://ftp.oreilly.com/pub/conference/java2001/Portwood_Reflection.ppt ] Without reflection

13 13 A factory design pattern example, cont’d [ ftp://ftp.oreilly.com/pub/conference/java2001/Portwood_Reflection.ppt ] With reflection

14 14 Reflecting arrays [ http://www-128.ibm.com/developerworks/java/library/j-dyn0603/ ] In Java, arrays are objects. Like all objects, they have classes. If you have an array, you can get the class of that array using the standard getClass method, just as with any other object. However, getting the class without an existing instance works differently than for other types of objects.  Even after you have an array class, there’s not much you can do with it directly – the constructor access provided by reflection for normal classes doesn’t work for arrays, and arrays don’t have any accessible fields. (Only the base java.lang.Object methods are defined for array objects.)

15 15 Reflecting arrays, cont’d [ http://www-128.ibm.com/developerworks/java/library/j-dyn0603/ ] The special handling of arrays uses a collection of static methods provided by the java.lang.reflect.Array class. The methods in this class let you create new arrays, get the length of an array object, and read and write indexed values of an array object. Next slide: a useful method for effectively resizing an existing array. It uses reflection to create a new array of the same type, then copies all the data across from the old array before returning the new array.

16 16 Reflecting arrays, cont’d [ http://www-128.ibm.com/developerworks/java/library/j-dyn0603/ ]

17 17 More on reflecting arrays [ http://www.java2s.com/Code/JavaAPI/java.lang/ ClassgetComponentType.htm ]

18 18 Generics in depth [ http://www.angelikalanger.com/Conferences/Slides/ JavaGenerics-JavaOne-2005.pdf ] Quick reminder: non-generic collections – lots of casts required. No compile-time checks. generic collections – homogeneous, no casts required, compile-time checking.

19 19 Definition of generic types Type variable: “placeholder” for an unknown type. NOT REALLY A TYPE: not allowed in new expressions; cannot be derived from.

20 20 Type parameter bounds Bounds = supertype of a type variable (Comparable is the supertype in the example above). What for? To make available non-static members of a type variable. Limitations: gives no access to constructors or static methods.

21 21 Using generic types with concrete type arguments, without type arguments (yes!), with wildcard arguments. Concrete instantiation Raw type (permitted for compatibility – mixing generics with old code)

22 22 Wildcard instantiation

23 23 Wildcards

24 24 Bounded wildcard example Consider a method that draws objects from a class hierarchy of shapes. Cannot draw e.g. a list of circles because List is NOT a subtype of List.

25 25 Bounded wildcard example, cont’d Fix with ‘?’ ?? Use upper bound wildcard to solve the problem.

26 26 Defining a generic type – case study

27 27 Defining constructors. Naïve approach...

28 28 Defining constructors. Quick and dirty fix...

29 29 Same type constructor argument

30 30 Problem with the prev example: useful cases are also rejected Note: the abstract class java.lang.Number is the superclass of classes Byte, Double, Float, Integer, Long, and Short.

31 31 Compatible type constructor argument

32 32 Equivalent implementation

33 33 Regexps Regular expression (regexp) is a string of characters that defines a pattern used to search for a matching string. Can be used as a tool to search, edit or manipulate text or data. Common use: validation of date, zip code, email, IP etc. entries, searching for comment blocks in code, searching for word variants (eg. AE and BE). Applications: text editors, tokenizers and parsers, text compressors, log analyzers...

34 34 Regexps in Java Regexp are supported by many languages (or their standard libs): Perl, PHP, JavaScript, Python, Ruby and more. They're in Java JDK too (since v1.4.0). Just use the package java.util.regex. Interestingly, some basic functionality is already implemented in class String. Namely, methods matches, replacesAll, split. bool matches(String regexp) – tells if this string matches the given regular expression. If matches entirely! Example: str = "color"; out.println(str.matches("colo(r|ur)")); // true str = "blue color"; out.println(str.matches("colo(r|ur)")); // false

35 35 Using regexp with String methods, cont’d Prev. example: you could also write str.matches("^colo(r|our)$") with the same effect. The caret ^ requires the beginning of the string. The $ sign allows a match at the string end only. ^ and $ are called anchors. Other useful anchors: \b: word boundary \B: non-word boundary Prev. example: str.matches("colo.r") works too (matches “colour” only, not “color”). '.' denotes any char (except for '\n' – by default!)

36 36 Using regexp with String methods, cont’d [ http://www.regular-expressions.info/java.html ] str.split("regex") splits the string at each regex match. The method returns an array of strings where each element is a part of the original string between two regex matches. The matches themselves are not included in the array. Use str.split("regex", n) to get an array containing at most n items. The last item in the string is the unsplit remainder of the original string.

37 37 Backslash mess [ http://www.regular-expressions.info/java.html ] In literal Java strings the backslash is an escape character. The literal string "\\" is a single backslash. In regular expressions, the backslash is also an escape character. The regular expression \\ matches a single backslash. This regular expression as a Java string, becomes "\\\\". That's right: 4 backslashes to match a single one. (That's because you actually have 2 compilers here: javac and the pattern compiler...)

38 38 What’s that? [ http://www.regular-expressions.info/tutorial.html ] In []: any of the specified chars allowed. '-' specifies a range, so we have all uppercase letters, all digits, dot, underscore, % sign and a hyphen. The + after [.....] means: occurs once or more times. Then we have the @ sign. Then we have a series of letters, digits and hyphens. Finally we have a single dot followed by between 2 and 4 letters. So, this is an email address (assuming uppercase letters in it).

39 39 Predefined character classes [ http://java.sun.com/developer/technicalArticles/releases/1.4regex/ ]

40 40 More on character classes [ http://java.sun.com/docs/books/tutorial/essential/regex/char_classes.html ]

41 41 Pattern and Match classes [ http://www.regdeveloper.co.uk/2006/03/24/java_regex_tutorial/ ] To deal with regexps, we usually create a Pattern object (remember: import java.util.regex.*). Use the static method Pattern Pattern.compile(String) to compile a regexp into a Pattern. A Matcher object is the engine that interprets the pattern and performs match operations against an input string. To use it, call Pattern’s (static) method matcher on behalf of this Pattern.

42 42 Pattern and Match classes, cont’d [ http://www.regdeveloper.co.uk/2006/03/24/java_regex_tutorial/ ]

43 43 Let's extend a bit the previous example... Output: Found the text "str" starting at pos 9 and ending at pos 12. So the equivalent of m.group() is s.substring(m.start(), m.end()). Exercise: modify the code above to print all the matching sequences, not only the first (leftmost) of them.

44 44 Greedy matching [M.Habibi, Java Regular Expressions: Taming the java.util.regex Engine, Apress, 2004, chapter 3] The nature of the regex engine is to match as much as it possibly can (so it’s greedy), so long as that match doesn’t interfere with another matching subexpression somewhere else in the pattern. Below: greedy qualifiers.

45 45 Greedy matching, how it works (example) [M.Habibi, Java Regular Expressions: Taming the java.util.regex Engine, Apress, 2004, chapter 3] Consider the string "J23Superagent". And the pattern (\w)(\d\d)(\w+) (Remember, smth like String regex = "(\\w+)(\\d\\d)(\\w+)"; in Java code…) The leftmost part of the pattern (the first (\w) in this example), tries to match as much as possible. When it can't match anymore, the next part of the pattern is evaluated. If that second part of the pattern fails to find any matches, then the first matching pattern starts to slowly release characters that it has already collected, thus providing the second part of the pattern with more opportunities to match. greedy-generous behavior

46 46 Greedy matching, how it works (example, cont’d) [M.Habibi, Java Regular Expressions: Taming the java.util.regex Engine, Apress, 2004, chapter 3] At this point, one of two things can happen. 1st alternative: the latter group can finally achieve a match, in which case the first group stops releasing characters. 2nd alternative: the latter group can fail to match, even with the characters made available to it from the earlier group. If this happens, then the group that was releasing characters, in effect, collects those released characters again, and the regex engine goes on. If a later subexpression again fails to match, then the process is repeated.

47 47 Greedy matching, how it works (example, cont’d) [M.Habibi, Java Regular Expressions: Taming the java.util.regex Engine, Apress, 2004, chapter 3] Now, consider a very similar pattern: (\w+)(\d\d)(\w+)

48 48 Greedy matching, how it works (example, cont’d) When group(1) runs, (\w+) examines every character in the candidate String J23SuperAgent. That is, J is explicitly considered, passes inspection, and is put into the matching bag for this group. Because this pattern is greedy and has + after \w, it continues. Next, 2 is explicitly considered and passes inspection. Then, the digit 3 is considered. This continues until the entire String J23SuperAgent is consumed.

49 49 Greedy matching, how it works (example, cont’d) After group(1) is satisfied, group(2), namely (\d\d), gets an opportunity. Because group(2) is unable to match anything at all, group(1) releases the ‘t’ character at the end of J23SuperAgent. The ‘t’ char is considered by group(2), found not be a digit, and considered not to be sufficient. Thus, group(1) releases the ‘n’. group(2) inspects it, and of course rejects it. Thus, group(1) releases the ‘e’ char (just before the ‘n’ in “J23SuperAgent”). Etc. until group(1) has released every character except J. Finally, the release of the two digits (‘2’ and ‘3’) allow group(2) to match. Now group(1) has J and group(2) has 23.

50 50 Greedy matching, how it works (example, cont’d) Finally, group(3) gets an opportunity to run. It starts examining the candidate String J23SuperAgent at the point immediately following the ‘3’ digit. And because it's greedy, it matches the entire string SuperAgent. Conclusion: the two patterns (\w)(\d\d)(\w+) and (\w+)(\d\d)(\w+) produce exactly the same result when applied to the String J23SuperAgent but at vastly different efficiency costs.

51 51 Quantifier types [ http://www.cis.upenn.edu/~matuszek/cit591-2002/Lectures/java-regex.ppt ] A greedy quantifier will match as much as it can, and back off if it needs to A reluctant quantifier will match as little as possible, then take more if it needs to –You make a quantifier reluctant by appending a ?: X?? X*? X+? X{n}? X{n,}? X{n,m}? A possessive quantifier will match as much as it can, and never let go –You make a quantifier possessive by appending a +: X?+ X*+ X++ X{n}+ X{n,}+ X{n,m}+

52 52 Quantifier examples [ http://www.cis.upenn.edu/~matuszek/cit591-2002/Lectures/java-regex.ppt ] Suppose your text is aardvark –Using the pattern a*ardvark (a* is greedy): The a* will first match aa, but then ardvark won’t match The a* then “backs off” and matches only a single a, allowing the rest of the pattern (ardvark) to succeed –Using the pattern a*?ardvark (a*? is reluctant): The a*? will first match zero characters (the null string), but then ardvark won’t match The a*? then extends and matches the first a, allowing the rest of the pattern (ardvark) to succeed –Using the pattern a*+ardvark (a*+ is possessive): The a*+ will match the aa, and will not back off, so ardvark never matches and the pattern match fails

53 53 Greedy vs Reluctant vs Possessive, replace example

54 54 Matcher class, closer look [ http://www.cis.upenn.edu/~matuszek/cit591-2002/Lectures/java-regex.ppt ] Assume have a matcher m, –m.matches() returns true if the pattern matches the entire text string, and false otherwise –m.lookingAt() returns true if the pattern matches at the beginning of the text string, and false otherwise –m.find() returns true if the pattern matches any part of the text string, and false otherwise If called again, m.find() will start searching from where the last match was found m.find() will return true for as many matches as there are in the string; after that, it will return false When m.find() returns false, matcher m will be reset to the beginning of the text string (and may be used again)

55 55 Matcher class, closer look, cont’d [ http://www.cis.upenn.edu/~matuszek/cit591-2002/Lectures/java-regex.ppt ] After a successful match, m.start() will return the index of the first character matched After a successful match, m.end() will return the index of the last character matched, plus one If no match was attempted, or if the match was unsuccessful, m.start() and m.end() will throw an IllegalStateException –This is a RuntimeException, so you don’t have to catch it Why m.end() returns the index of the last character matched plus one? Because it’s convenient; this is just what most String methods require: –For example, "Now is the time".substring(m.start(), m.end()) will return exactly the matched substring m.group() is same as s.substring(m.start(), m.end())

56 56 Groups (\1 – first group, \2 – second etc.)

57 57 Groups, a bit different example [ http://www.cis.upenn.edu/~matuszek/cit591-2002/Lectures/java-regex.ppt ] Suppose we want to move all the consonants at the beginning of a given string word (if any) to its end (so string  ingstr). Pattern p = Pattern.compile("([^aeiou]*)(.*)"); Matcher m = p.matcher(word); if (m.matches()) { System.out.println(m.group(2) + m.group(1)); }

58 58 Time for a little something [ http://www.javalobby.org/eps/more-puzzlers/ ] Answer: d. (Prints just “false”.) Because the + operator binds tighter than ==.

59 59 Obvious fix But wait. pig and dog are both final. Can’t we use the == operator then? With "Animals... " + (pig == dog) expression? No. That's because evaluation of dog needs invoking a method (length(), for the object pig, in our case) which must be done in the runtime. Hence, pig and dog are physically separate strings. But note: final String pig = "length: 10"; final String dog = "length: 10"; // here pig == dog !

60 60 What does it print? [ http://www.javalobby.org/eps/more-puzzlers/ ]

61 61 Two fixes needed 1.Remove the bug: should be && instead of & in the predicate thirdElementIsTree. && has short-circuit evaluation, & has full evaluation. 2. Remove the inefficiency: not try... catch to exit the loop but normal iteration over an array. For convenience, use: for(int[] test: tests) if (thirdElementIsThree(test))... Test (with the &  && fix), Athlon64 3000+, WinXP, JDK 1.5: try... catch version, repeated 10^7 times: 68.8s for(int[] test: tests) version, repeated 10^7 times: 0.53s.

62 62 “The Mod Squad” [ http://www.javalobby.org/eps/more-puzzlers/ ]

63 63 Answer: Throws an exception: Array of out bounds exception Two problems in here. One: there are more negative int numbers than positive numbers. Consequently, there is no integer equal to –Integer.MIN_VALUE....And Math.abs(Integer.MIN_VALUE) returns Integer.MIN_VALUE (yes, the same neg. number)! Problem two: a % b has the sign of a. E.g. –4 % 3 is –1 in Java.

64 64 Fix it then

65 65 The Joy of Hex [ http://www.javalobby.org/eps/more-puzzlers/ ] Answer:

66 66 The Joy of Hex, cont’d Because we add a long constant to an int constant, the int constant is sign-extended into a long prior to the addition.

67 67 The Joy of Hex, moral


Download ppt "Object Oriented Programming in Java Lecture 7 (Dynamic Java and reflection. Generics in depth. Regexps) Szymon Grabowski"

Similar presentations


Ads by Google