SageTV Community  

Go Back   SageTV Community > SageTV Development and Customizations > SageTV Studio
Forum Rules FAQs Community Downloads Today's Posts Search

Notices

SageTV Studio Discussion related to the SageTV Studio application produced by SageTV. Questions, issues, problems, suggestions, etc. relating to the Studio software application should be posted here.

Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old 02-26-2009, 01:38 PM
Ikarius's Avatar
Ikarius Ikarius is offline
Sage Advanced User
 
Join Date: Aug 2008
Posts: 84
Beginning Java tutorial

Okay, so I recently went through the process of learning enough Java to do a bit of utility processing. I'm an experienced programmer, but had never touched java, and finding all the bits necessary to make this work was much more painful than actually writing the java code for me. Thus, I figured I'd write up a tutorial on going from scratch, to having a function which can be called from SageTV in a .jar file. This tutorial is intended for someone who is familiar with programming, but not with java. As I'm entirely new to java, I may have missed bits, in which case I'd welcome corrections.

This tutorial assumes only using the java JDK command-line tools. The tools involved are "javac" (the java compiler) and "jar" (assembles .jar files). You'll also need a text editor.

A few background bits-

You will write your code in ".java" files, javac will compile them to ".class" files, and jar will package those into ".jar" files.

If I call a routine such as mypackage.Util.GetTheme(). In the sage studio calling convention this would be mypackage_Util_GetTheme(). There are several parts to what is being called. "mypackage" is the name of the package, "Util" is the name of the class, and "GetTheme" is the name of the method.

Translating this to the bits necessary to arrive there-
1. Someone created a file named "Util.java", which contained the code defining the class "Util", and the class method "GetTheme".
2. The first line of the java file was "package sagemc;"
3. Once the java file was compiled into a .class file, it was placed in a directory named "mypackage", and the jar utility was run from the parent directory.

Next up, example code for a java file. This code is a silly example, as you could simply call a straight java function to accomplish this, but it contains the fundamentals needed.

Code:
 1: package mypackage;
 2: 
 3: import java.lang.reflect.InvocationTargetException;
 4: import sage.SageTV;
 5:
 6:
 7: public class Util extends java.lang.Object {
 8:
 9:   public static String GetLowerCaseTitle( Object o1 ) {
10:     String s1 = new String();
11:     try
12:     {
13:       s1 = (String) SageTV.api("GetMediaTitle", new Object[] { o1 } );
14:     }
15:     catch  (Exception e)
16:     {
17:       return "";
18:     }
19:     s1 = s1.toLowerCase();
20:     return s1;
21:   }
22:}
I'll walk through several important bits here. Note that the Line numbers and colons are NOT actually in the file. They are there so I can conveniently refer to lines of code.

Line 1 is the package name. It's required, and it needs to match the directory name the .class file is placed in.

Lines 3 and 4 are necessary imports to call the SageTV api. Imports are similiar to #include in C, require in perl, etc- they tell java what libraries you're going to use. The first import is java's support for exception handling- sagetv's API requires this, and the second import is the SageTV api itself.

Line 7 gets interesting. It tells java the name of the class you're defining. The name of the class should match the name of the .java file you've created. The modifier "public" tells java that this class should be visible to external code when the library is imported. The "extends java.lang.Object" tells java that this class should be a subclass of the Object class. Nearly everything in java is a subclass of Object, it allows you to inherit some useful methods, so it's recommended until you know what you're doing and have a specific reason to change it.

Line 9- Okay, so we're defining a method which returns a String, and it takes a single parameter which is an Object. Because most things are subclasses of Object, this means you could pass nearly anything to this function. Because the SageTV objects are not strongly typed, unless you're using a 3rd party version of the Sage API, you need to pass them as Objects. The modifier "public" means the same thing it did in the Class definition. The modifier "static" means that this routine can be called without creating an instance of the class. That means you don't have to create a variable, instantiate the class by calling "new", and use that variable to call this method.

Lines 11-18 are an example of calling the SageTV API from java. You *must* encase SageTV API calls in a try-catch construct. If you hit the code inside the catch{ } block, it means something went wrong, so it should contain code which assumes your call to the sage API did not succeed. The (String) is a typecast- it tells java that the Sage API call should return a string, and to treat it as such. The "GetMediaTitle" is the name of the Sage API function you're calling. The code "new Object[] { o1 }" tells java to build an array of objects, and fill populate that array with a single element, the object "o1", which was passed to this method. If you were passing additional arguments to the SageTV API, you would add additional variables between the curly braces, i.e. "new Object[] { o1, SomeString, SomeOtherString }".

That covers the code. Now on to preparing it to be used from SageTV.

First, the java needs to be compiled. The command-line tool "javac" does this. In order to compile this code, I need to tell javac where to find the "sage" package. In the directory containing the .java file, I will run the following command:

Code:
javac -cp "c:\Program Files\SageTV\SageTV\Sage.jar"  Util.java
The -cp parameter tells javac about additional places to look for libraries, so we point it to the "Sage.jar" file in order to find the Sage API code. This command should create a file "Util.class" in the current directory if the code compiles successfully.

Now, we're going to create a .jar file with the compiled code in it.
Code:
mkdir mypackage
copy Util.class mypackage
jar -cf mypackage.jar mypackage
Here, we create a directory that matches the package name, copy the compiled class into it, and tell the java archiver to create the file "mypackage.jar", which should contain anything in the directory "mypackage". If everything worked, you should be able to copy this .jar file into the JARs subdirectory for Sage, restart the sage server or client, and use Studio to call the function. In this case, it expects to recieve a mediafile object, and will return a string. The example code could be called like this:
somevar = mypackage_Util_GetLowerCaseTitle( somemediafile ). Also note that a .jar file is actually a .zip file with a different extension. The jar utility command-line is based on the syntax of the UNIX "tar" command, and it produces some extra information (a manifest) which it puts in the file along with the .class files.

For reading up on java itself, the java API reference is useful:
http://java.sun.com/j2se/1.5.0/docs/...view-tree.html

I also found the following site to cover useful topics and examples:
http://leepoint.net/notes-java/index.html


As always, corrections and comments are welcome.

Cheers
Ikarius
__________________

SageTV 6.6.2, SageMC+CenterSage Theme
Server: Intel Core2 Q6600, 8gb memory, 3x 1tb WD EACS drives, software RAID5 2tb capacity, 4gb Flash boot drive, Ubuntu 8.0.4 Server edition
Capture: 1x HD-PVR -> Motorola DTC6200
Clients: 1x STX-HD100 1x STX-HD200, Windows & OSX Clients

Last edited by Ikarius; 02-26-2009 at 01:44 PM.
Reply With Quote
  #2  
Old 02-26-2009, 01:46 PM
jaminben jaminben is offline
Sage Icon
 
Join Date: Sep 2007
Location: Norwich, UK
Posts: 1,754
Send a message via MSN to jaminben
Nice job Ikarius, out of my league but it may come in useful once I gain some more experience.

__________________
Server - Win7 64bit, 2.4Ghz Intel Core 2 Duo, TBS 6284 PCI-E Quad DVB-T2 Tuner, 3 x HD200 & 1 x HD300 extenders
Reply With Quote
  #3  
Old 02-26-2009, 02:19 PM
evilpenguin's Avatar
evilpenguin evilpenguin is offline
SageTVaholic
 
Join Date: Aug 2003
Location: Seattle, WA
Posts: 3,696
Thanks for the tutorial, I've always wondered how it worked.
Reply With Quote
  #4  
Old 02-26-2009, 03:13 PM
GKusnick's Avatar
GKusnick GKusnick is offline
SageTVaholic
 
Join Date: Dec 2005
Posts: 5,083
Some comments based on my own experience of learning Java:

Quote:
Originally Posted by Ikarius View Post
This tutorial assumes only using the java JDK command-line tools. The tools involved are "javac" (the java compiler) and "jar" (assembles .jar files). You'll also need a text editor.
By limiting yourself to command-line tools, I think you're making it harder than it needs to be. A good Java IDE like Eclipse or Netbeans will automatically keep track of what needs to be compiled, call the compiler, package the results in a JAR, and so forth, all with one click. It will also organize your packages into directories and provide templates for creating new classes that fill in most of the boilerplate for you. For Java newbies, this may be a smarter way to go.

Quote:
Originally Posted by Ikarius View Post
Line 1 is the package name. It's required, and it needs to match the directory name the .class file is placed in.
Note that package names must be unique in the known universe. If you choose "sagestuff" or something similar for your package name, there's a good chance some other newbie will also be trying to use that same package name, which could be bad. The Java authorities recommend that you base package names on a domain name that you own, e.g. com.mydomain.mypackage instead of just mypackage, to minimize the chance of a name collision.

Quote:
Originally Posted by Ikarius View Post
The modifier "public" tells java that this class should be visible to external code when the library is imported.
Specifically, "public" says that the class should be visible to code in other packages (not other .java or .jar files). Omitting "public" means the class will be visible only to other classes in the same package (even if they reside in different .java or .jar files).

Quote:
Originally Posted by Ikarius View Post
The "extends java.lang.Object" tells java that this class should be a subclass of the Object class. Nearly everything in java is a subclass of Object, it allows you to inherit some useful methods, so it's recommended until you know what you're doing and have a specific reason to change it.
Unless I'm mistaken, everything in Java (except for primitive types like int) is a subclass of Object and inherits from Object whether or not you say "extends java.lang.Object".

Quote:
Originally Posted by Ikarius View Post
Lines 11-18 are an example of calling the SageTV API from java.
Not to plug my own code, but again, for beginners it might be simpler to use existing API wrapper functions to hide all this complexity.
__________________
-- Greg
Reply With Quote
  #5  
Old 02-26-2009, 03:37 PM
Ikarius's Avatar
Ikarius Ikarius is offline
Sage Advanced User
 
Join Date: Aug 2008
Posts: 84
Greg,
Useful clarifications, those

You've got a strong point in favor of folks using your API, since just about anyone serious about developing STVi's probably ought to be using your studio tools and your STVi export, when then requires your .jar file for proper importing. At that point, the issue of dependency on another .jar is already moot. I also favor the strongly-typed API to the original approach.

There was at one point some rumbling about your studio extension stuff getting rolled into core, any word on that?
__________________

SageTV 6.6.2, SageMC+CenterSage Theme
Server: Intel Core2 Q6600, 8gb memory, 3x 1tb WD EACS drives, software RAID5 2tb capacity, 4gb Flash boot drive, Ubuntu 8.0.4 Server edition
Capture: 1x HD-PVR -> Motorola DTC6200
Clients: 1x STX-HD100 1x STX-HD200, Windows & OSX Clients
Reply With Quote
  #6  
Old 02-26-2009, 06:00 PM
GKusnick's Avatar
GKusnick GKusnick is offline
SageTVaholic
 
Join Date: Dec 2005
Posts: 5,083
Quote:
Originally Posted by Ikarius View Post
There was at one point some rumbling about your studio extension stuff getting rolled into core, any word on that?
Not that I've heard. My guess is that probably nothing much will happen along those lines as long as my hook code continues to work. If they ever redesign Studio in such a way as to break my hooks, that would be a plausible time for them to roll the hooks into the core.
__________________
-- Greg
Reply With Quote
  #7  
Old 02-26-2009, 07:30 PM
stuckless's Avatar
stuckless stuckless is offline
SageTVaholic
 
Join Date: Oct 2007
Location: London, Ontario, Canada
Posts: 9,713
I pretty much second everything that Greg stated. While the initial appearance of just using the command line may seem "easier", using tools like eclipse/netbeans (both free) can really aid in development. Also I think that you'd come to enjoy the autocomplete features of the IDE, epecially when you are using other libraries, such as Greg's api.

If you do decide to use Eclipse, here's a rough quick start....

Create a new Project
File -> New -> Java Project (enter name, click enter)

Create a new File
Right click on the "src" folder, then select File -> New -> Class (Enter package and name)

That gives you a new skeleton source file.

Add a Jar
If you want to add a jar file to your project (ie, greg's jar), simply copy it into your project dir, and "refresh" your project files, if you don see it (F5), and then right click on the jar file and select "Build Path -> Add to Build Path"

create your Jar File
Right click on your Project, then select Export -> Java -> Jar File (Follows prompts)

I'll be honest, in all the years I did c programming, I never used an IDE, and for many years, in Java, I didn't either, and now I can't help but to wonder how much time I wasted by not using an IDE.
Reply With Quote
  #8  
Old 02-26-2009, 08:05 PM
GKusnick's Avatar
GKusnick GKusnick is offline
SageTVaholic
 
Join Date: Dec 2005
Posts: 5,083
Forgive the digression, but I was an IDE designer in a previous job, and one of the toughest issues we ran into, no matter how sexy we made the IDE, was getting developers to give up their beloved command-line tools.

You'd think programmers would be at the forefront of adopting new data formats and new storage technologies. But decades into the age of spreadsheets, PDF documents, and object-oriented databases, most programmers would still rather store their source as plain text files, edit it character by character (despite the risk of errors), and process it using command-line tools, just like their fathers did 40 years ago. Even modern IDEs with autocompletion, auto-indent, interactive syntax checking, and one-click build commands are still working with text files and command-line tools under the hood. (SageTV Studio is a notable exception to this.)

My group's goal was to replace all that with a truly object-oriented IDE in which source code was stored in a database in pre-parsed form, so that it was literally impossible to commit a syntax error. There were huge advantages to this in compiler extensibility, program transformation, and code analysis, but our project failed all the same because we couldn't find any users willing to give up the text-file-and-command-line paradigm.
__________________
-- Greg
Reply With Quote
  #9  
Old 02-26-2009, 10:47 PM
chrishallowell chrishallowell is offline
Sage Advanced User
 
Join Date: Jan 2008
Posts: 169
This is excellent!
If someone wanted to use Greg's tool, what would the code in post #1 look like?
Reply With Quote
  #10  
Old 02-26-2009, 10:58 PM
jreichen's Avatar
jreichen jreichen is offline
Sage Icon
 
Join Date: Jul 2004
Posts: 1,192
I agree with Ikarius starting with the command line tools. I think it helps to understand the basics before moving to an IDE that does a lot for you, plus you'll know what you're looking at in the IDE when you look through the project's contents (src, classes, libraries, etc). But I wouldn't do much more than that before moving to an IDE. And stuckless nicely summarized how to do the same things in Eclipse. Nice job to both of you

Quote:
Originally Posted by GKusnick View Post
Unless I'm mistaken, everything in Java (except for primitive types like int) is a subclass of Object and inherits from Object whether or not you say "extends java.lang.Object".
You're exactly right. And with boxing and unboxing in Java 5, you can pretty much treat primitives (int, boolean, etc) like their object-wrapper counterparts (Integer, Boolean, etc), albeit with some limitation.
__________________
Server: Intel Core i5 760 Quad, Gigabyte GA-H57M-USB3, 4GB RAM, Gigabyte GeForce 210, 120GB SSD (OS), 1TB SATA, HD HomeRun.
Extender: STP-HD300, Harmony 550 Remote,
Netgear MCA1001 Ethernet over Coax.
SageTV: SageTV Server 7.1.8 on Ubuntu Linux 11.04, SageTV Placeshifter for Mac 6.6.2, SageTV Client 7.0.15 for Windows, Linux Placeshifter 7.1.8 on Server and Client
, Java 1.6.
Plugins: Jetty, Nielm's Web Server, Mobile Web Interface.

Reply With Quote
  #11  
Old 02-26-2009, 11:16 PM
GKusnick's Avatar
GKusnick GKusnick is offline
SageTVaholic
 
Join Date: Dec 2005
Posts: 5,083
Quote:
Originally Posted by chrishallowell View Post
If someone wanted to use Greg's tool, what would the code in post #1 look like?
Something like this:

Code:
package com.mydomain.mypackage;

import gkusnick.sagetv.api.*;

public class Util
    {
    public static String GetLowerCaseTitle(Object o)
        {
        return GetLowerCaseTitle(API.apiNullUI.mediaFileAPI.Wrap(o));
        }
    
    public static String GetLowerCaseTitle(MediaFileAPI.MediaFile mf)
        {
        return mf.GetMediaTitle().toLowerCase();
        }
    }
The reason for the two overloads has to do with where you're calling it from. If you're calling from Studio code with a raw MediaFile object, the first overload will be invoked. This will wrap the raw object in a strongly-typed wrapper object and pass it to the second overload, where mf.GetMediaTitle does the actual work of unwrapping the argument to recover the raw SageTV API object and calling the appropriate API function on it.

(There are further complexities if you're calling API functions that require a UI context (e.g. GetCurrentMediaFile()), in which case apiNullUI won't do what you want, and you'll have to instantiate an API object with the correct context.)
__________________
-- Greg
Reply With Quote
  #12  
Old 02-26-2009, 11:20 PM
david1234 david1234 is offline
Sage Aficionado
 
Join Date: Nov 2007
Location: Beaverton, OR
Posts: 313
I apologize in advance for being primarily a maintenance programmer at work, so reading code is what I do a lot of.

Just 2 small nitpicks, but otherwise a good start...

1. In general, since all objects inherit from Object, it is redundant to specify "extends Object". Plus, by specifying the inheritance, it implies that something other than the standard Object extension is really supposed to be going on. As a programmer reading your code, I would assume that this is a typo, and you intended to inherit from something and your editor plugged in object without you catching it.

2. I'm not familiar with the SageTV api, but you generally want to catch specific exceptions rather than the most generic Exception. By catching Exception you catch every possible error, and it's unlikely that your catch block can handle every form of exception in the java api.

3. I actually have 3 nitpicks, but how code blocks and braces are formatted is a religious issue I'll just say that I would rewrite that block before working on it. My preference is the Sun Java style guide.

My personal motto when writing code is "Least Work"- code should do what it needs to do and absolutely nothing more! If a method can't fix the problem that led to the exception then it shouldn't try to pretend it does. A method should simply declare that it might throw whatever the api methods it calls throw, and let some other part of the program (that does know what to do) deal with it.

Thinking in Java by Bruce Eckell (probably not spelled right) is a very good start for anybody who is already somewhat familiar with object-oriented coding. It used to be available for free to download the whole book online.

Quote:
Originally Posted by Ikarius View Post

Code:
 7: public class Util extends java.lang.Object {
11:     try
12:     {
13:       s1 = (String) SageTV.api("GetMediaTitle", new Object[] { o1 } );
14:     }
15:     catch  (Exception e)
16:     {

Last edited by david1234; 02-26-2009 at 11:27 PM.
Reply With Quote
  #13  
Old 02-26-2009, 11:38 PM
GKusnick's Avatar
GKusnick GKusnick is offline
SageTVaholic
 
Join Date: Dec 2005
Posts: 5,083
Quote:
Originally Posted by david1234 View Post
A method should simply declare that it might throw whatever the api methods it calls throw, and let some other part of the program (that does know what to do) deal with it.
That's reasonable as a general policy. However in the specific case of SageTV.api, InvocationTargetException simply means that you spelled the method name wrong in the first argument. Once you've debugged your code, you'll never see this exception in practice, and it's an annoyance to have to propagate InvocationTargetException out of every method that calls a SageTV API directly or indirectly. That's why I coded my API wrappers to eat those exceptions at the bottommost layer instead of propagating them.
__________________
-- Greg
Reply With Quote
  #14  
Old 02-27-2009, 06:41 AM
stuckless's Avatar
stuckless stuckless is offline
SageTVaholic
 
Join Date: Oct 2007
Location: London, Ontario, Canada
Posts: 9,713
Again, I second greg's comments as well. It's a reasonable policy to only consume the exceptions that you care about, but at the same time, when you are producing libraries that are going to be consumed by others, forcing them to catch and handle every little exception leads to the consumer spending more time catching exceptions rather than actually writing code.

In many cases you don't care "why" it failed, just the fact that it did.

A similiar notion exists for NullPointerException. As soon as you have an object you should always check for null. But checking for null is rather tedious when you are dealing with a bunch of nested objects, etc, so in many cases a programmer will wrap an entire block around a RuntimeException or Exception and catch and fail if anything goes wrong. The nice thing about exceptions (even invocationtaget ones), is that they can tell you why and where the code failed, so logging that information because a crucial part of development.

In many cases, it's a fine line between trying to write textbook code and trying to write code that actually makes it out the door, but IDEs are making it easier to bridge the gap.
Reply With Quote
  #15  
Old 02-27-2009, 10:47 AM
david1234 david1234 is offline
Sage Aficionado
 
Join Date: Nov 2007
Location: Beaverton, OR
Posts: 313
Quote:
Originally Posted by stuckless View Post
In many cases you don't care "why" it failed, just the fact that it did.
This actually fits well into my "least work" style- if logging the error is the correct action, then that's what the code should do. It just shouldn't catch things for the sake of catching them, and then rethrow without doing anything, or worse yet, eating an error that another layer might need to know about
Code:
catch ( Exception ) { /*eat this*/ }
I haven't worked with the SageTV api, so like I said, I was trying to comment generally about the Java.
Reply With Quote
  #16  
Old 02-27-2009, 11:03 AM
Ikarius's Avatar
Ikarius Ikarius is offline
Sage Advanced User
 
Join Date: Aug 2008
Posts: 84
Useful info here indeed.

Not unexpectedly, I still have some learning to do, and this thread should make things a bit easier for others trying to get started with Java. I'll go back and tweak some areas soon. There are a few bits which will take me more digestion before I'm comfortable rewriting.

Cheers
Ikarius
__________________

SageTV 6.6.2, SageMC+CenterSage Theme
Server: Intel Core2 Q6600, 8gb memory, 3x 1tb WD EACS drives, software RAID5 2tb capacity, 4gb Flash boot drive, Ubuntu 8.0.4 Server edition
Capture: 1x HD-PVR -> Motorola DTC6200
Clients: 1x STX-HD100 1x STX-HD200, Windows & OSX Clients

Last edited by Ikarius; 02-27-2009 at 11:05 AM.
Reply With Quote
  #17  
Old 02-27-2009, 03:42 PM
Ikarius's Avatar
Ikarius Ikarius is offline
Sage Advanced User
 
Join Date: Aug 2008
Posts: 84
Just a comment on the "Least Work" philosophy expressed above, as I think some folks might extend it too far. There are a lot of cases where languages provide "implicit" and "explicit" syntax; where when you write a bit of code, you don't need to specify everything, and the language chooses to "do the right thing" based on context. I'm personally of the opinion that using those shortcuts is Bad Practice, and you should almost always prefer "explicit" syntax, even though it's more typing.

Someone coming after you trying to read the code may be less familiar with the implicit shortcuts available in the language, and even if they are, it tends to be less clear for reading. That being said, I think what david expressed above was valid; this is simply trying to head off others reading more into it.


Cheers
Ikarius
__________________

SageTV 6.6.2, SageMC+CenterSage Theme
Server: Intel Core2 Q6600, 8gb memory, 3x 1tb WD EACS drives, software RAID5 2tb capacity, 4gb Flash boot drive, Ubuntu 8.0.4 Server edition
Capture: 1x HD-PVR -> Motorola DTC6200
Clients: 1x STX-HD100 1x STX-HD200, Windows & OSX Clients

Last edited by Ikarius; 02-27-2009 at 03:45 PM.
Reply With Quote
  #18  
Old 02-27-2009, 04:02 PM
david1234 david1234 is offline
Sage Aficionado
 
Join Date: Nov 2007
Location: Beaverton, OR
Posts: 313
To be clear- when I talk about "least work", what I'm talking about is breaking code into the smallest sized chunks that get the work done. The intent is to produce methods that do one thing and do it well.

I most definitely did't mean to imply that "lazy programming" is a good thing. In fact, I'm a huge fan of making variables and parameters "final" and specifying "this" whenever possible. The final tells the compiler that a parameter won't be modified, and this specifies that we are talking about a variable in the class instance. For the most part, "this." is implicit, but it's such good form to specify that it makes sense to add a few extra keystrokes.
Code:
private String text = "";
public void setText(final String text) { this.text = text; }
Reply With Quote
  #19  
Old 02-27-2009, 06:20 PM
GKusnick's Avatar
GKusnick GKusnick is offline
SageTVaholic
 
Join Date: Dec 2005
Posts: 5,083
Quote:
Originally Posted by Ikarius View Post
Just a comment on the "Least Work" philosophy expressed above, as I think some folks might extend it too far. There are a lot of cases where languages provide "implicit" and "explicit" syntax; where when you write a bit of code, you don't need to specify everything, and the language chooses to "do the right thing" based on context. I'm personally of the opinion that using those shortcuts is Bad Practice, and you should almost always prefer "explicit" syntax, even though it's more typing.
Yes and no. I think a better approach is to say what you mean, and no more. For instance in C there are various ways to test if a string is empty: you can say

Code:
if (!*s)
or you can say

Code:
if (strlen(s) == 0)
The first way involves less typing, but (a) explicitly relies on details of how strings are represented in C, and (b) is opaque to anyone not familiar with those details. The second way requires more typing but (a) says exactly what you mean in plain language and (b) avoids any explicit reliance on implementation specifics (leaving that up to strlen), and is therefore to be preferred.

Similarly, when iterating through collection, you have the choice of saying

Code:
for (int i = 0; i < c.size(); i++)
    {
    Object o = c.get(i);
    ...
    }
or (as of Java 5)

Code:
for (Object o : c)
    {...}
The first snippet is explicit about how to perform the iteration; the second just asks for an iteration and leaves it up to the collection to decide how to carry it out. In this case there's nothing gained in clarity, performance, or robustness from being too explicit. So again the best policy is to say just what you mean, i.e. iterate this collection, and leave it at that. Overspecifying details you don't really care about just gives you a chance to get them wrong and makes your code vulnerable to breakage if those details change.
__________________
-- Greg
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
No tutorial for remapping? SageGk SageTV EPG Service 2 12-14-2008 10:16 PM
Thanks for the manual, tutorial on Studio IVB SageTV Studio 1 12-31-2007 12:10 PM
Girder Tutorial for Dummies? pufftissue Hardware Support 0 03-09-2007 11:42 AM
Tutorial für SageTV in Deutschland marneb17 SageTV Germany 12 01-10-2006 08:43 AM
jukebox tutorial? sandyman SageTV Software 0 01-04-2005 11:47 PM


All times are GMT -6. The time now is 09:48 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2023, vBulletin Solutions Inc.
Copyright 2003-2005 SageTV, LLC. All rights reserved.